【问题标题】:Use LINQ-to-SQL to return an object that has child objects filtered使用 LINQ-to-SQL 返回已过滤子对象的对象
【发布时间】: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 似乎要困难得多。

【问题讨论】:

    标签: c# asp.net-mvc 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();
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多