实体框架4.0多个连接

时间:2013-01-25 20:26:35

标签: entity-framework entity-framework-4

这是我的真实世界的例子。 我有4张桌子:

  • 计划
  • 覆盖范围
  • CoveredMembers

每个人都可以有很多计划,每个计划都可以有很多计划。每个覆盖范围都可以有很多CoveredMembers。

我需要一个将在Plan.PlanType == 1CoveredMembers.TermDate == null上应用过滤器的查询。 此查询应该带回任何医疗类型计划未终止的人。

这个SQL语句就是这样做的:

SELECT Person.*, Plans.*, Coverages.*, CoveredMembers.* 
FROM Person P 
INNER JOIN Plan PL ON P.PersonID = PL.PersonID 
INNER JOIN Coverage C on PL.PlanID = C.PlanID 
INNER JOIN CoveredMember CM on C.CoverageID = CM.CoverageID 
WHERE CM.TermDate = NULL AND PL.PlanType = 1

我已经找到了如何使用匿名类型执行此操作,但我有时需要更新数据并保存回数据库 - 匿名类型是只读的。

我得到了一个使用JOIN工作的解决方案,但它只带回了人员(虽然按我需要的方式过滤)。然后我可以遍历每个人:

foreach (var person in persons) {
  foreach (var plan in person.Plans{
    //do stuff 
  }
}

但是不会为循环的每次迭代进行db调用吗?我有500人,每人有3个未终止的医疗计划,所以它会称db为1500次?

这就是为什么我想一次性将整个数据树从人员带到CoveredMembers。这不可能吗?

1 个答案:

答案 0 :(得分:0)

我相信这是由两部分完成的:

  1. 您的查询是根据您之前在此问题中讨论的条件确定您希望返回的人:Entity framework. Need help filtering results

  2. 正确设置所需实体的导航属性,以便加载:http://msdn.microsoft.com/en-us/data/jj574232.aspx

  3. 例如,如果您的Person实体看起来像:

    public class Person {
       public List<Plan> Plans {get; set;}
       ...
    }
    

    从dbcontext返回数据时,您还可以使用include选项显式预先加载:

     var people = context.People
             .Include(p => p.Plans)
             .ToList();
    ....
    

    如果这些是嵌套的 - 覆盖范围是计划的一部分,等等(它看起来像是这样):

     var people = context.People
             .Include(p => p.Plans.Select(pl=>pl.Coverage).Select(c=>c.CoveredMembers)))
             .ToList();
    ....
    

    我在这里对你的数据模型做了一些假设,上面的代码可能需要稍加调整。

    编辑

    我可能需要其他人在这里权衡,但我不认为你可以将where子句添加到这样的包含中(我上面的例子通过将include放在上下文对象上来引导你返回一个IQueryable,你的条件设置为在你的第一篇文章中解决(没有调用它的ToList()),然后使用你在上面写的代码而没有Where子句:

    从第一篇文章开始(你在这一篇文章中提供了不同的标准,但概念相同)

     var q = from q1 in dbContext.Parent
        join q2 in dbContext.Children
        on q1.key equals q2.fkey
        join q3 in  ........
        where q4.col1 == 3000
        select q1;
    

    然后:

    List<Person> people = q.Include(p => p.Plans
      .Select(pl => pl.Coverages)
      .Select(c => c.CoveredMembers).ToList();
    

    再一次,这样做不能排除故障 - 我相信我会花几次尝试来解决这个问题。