使用 LINQ-to-SQL 返回已过滤子对象的对象

Posted

技术标签:

【中文标题】使用 LINQ-to-SQL 返回已过滤子对象的对象【英文标题】:Use LINQ-to-SQL to return an object that has child objects filtered 【发布时间】:2011-08-29 16:10:14 【问题描述】:

我有一个与子成员表关联的 MembershipGroups 表。成员表有一个状态列,可以设置为活动或非活动。

我想选择所有 MembershipGroups 并且只选择他们的活跃成员

举个例子,

会员组

ID----标题

1-----第 1 组

2-----第 2 组

成员

MembershipGroupID-名称--状态

1-------------约翰----活跃

1-------------莎莉----不活跃

1-------------大卫---无效

我正在尝试创建一个类似于以下内容的查询(目前不起作用):

var query = from mg in db.MembershipGroups
where mg.Members.Status = "Active"
select mg

此示例的结果应返回 ID#1 的 MembershipGroup,只有一个子成员实体

如何使用 LINQ-to-SQL 来选择过滤子对象的父对象?如果我使用的是直接 T-SQL,那么这将是一个带有 where 子句的简单连接,但使用 LINQ-to-SQL 似乎要困难得多。

【问题讨论】:

【参考方案1】:

编辑 - 更新了返回 MemberShipGroup 对象的答案

var query = (from mg in db.MembershipGroups
            join m in db.Members.Where(mem => mem.Status == "Active")
            on mg.ID equals m.MembershipGroups into members
            select new
            
               MembershipGroup = mg,
               Members = members
            ).AsEnumerable()
              .Select(m => new MembershipGroup  
                           
                             ID = m.MembershipGroup.ID,
                             Title = m.MembershipGroup.Title,
                             Members = m.Members 
                           );

【讨论】:

这会返回什么类型的对象?我最终需要一个 MembershipGroup 对象列表。 @Dave Johansen - 它返回一个匿名类型。我更新了返回 MembershipGroup 对象的答案【参考方案2】:

在 LINQ to SQL 中,您可以使用 DataLoadOptions 上的 AssociateWith 方法在上下文级别设置您的子过滤器。

DataLoadOptions opt = new DataLoadOptions();
opt.AssociateWith<Member>(m => m.Status == "Active");
db.LoadOptions = opt;

有了这个,您可以简单地返回您的成员组(或使用 where mg.Any(group =&gt; group.Members.Status == "Active") 过滤它们以找到活动的组。然后,当您尝试深入了解该组的成员时,由于以下原因,只会返回活动的成员组加载选项。

另见http://msdn.microsoft.com/en-us/library/system.data.linq.dataloadoptions.associatewith.aspx。 警告一句话,一旦在上下文实例上设置了 LoadOptions,就无法更改它。您可能希望使用自定义上下文来使用此选项。

作为替代方案,您可以使用 LINQ to SQL 的继承模型创建一个 ActiveMember 类型,使用 Status 列作为您的鉴别器,然后在 MemberGroups 和 ActiveMembers 类型之间创建关联。如果您想走这条路线并且 EF 不支持 LoadOptions 的概念,这将是您需要使用 Entity Framework 对此进行建模的方法。

【讨论】:

【参考方案3】:

确保在查询中包含您尝试过滤的子对象。

例如

var 查询 = db.MembershipGroups .Include("成员") .Where(m => m.Members.Status == "活动");

【讨论】:

我看不到包含。它是特定于实体框架的吗?我正在使用 Linq-to-SQL。 是的,这是 LINQ to Entities,它可以工作 - 我在许多查询中都使用它。 这个不行,不能像 Linq 那样过滤成员 为我工作。我像这样使用它 var db = new DBcontext(); return db.ParentTable.Include("ChildTable").ToList();

以上是关于使用 LINQ-to-SQL 返回已过滤子对象的对象的主要内容,如果未能解决你的问题,请参考以下文章

通过 LINQ-to-SQl 加载数据集

linq-to-sql 是不是处理动态查询?

Linq-to-sql 使用 GroupBy 并返回满足条件的记录

使用Java过滤数组和子数组

如何关联不同 dbml 图上的 Linq-To-Sql 对象?

在运行时将实体对象添加到 LINQ-to-SQL 数据上下文 - SQL、C#(WPF)