【发布时间】:2014-06-11 12:17:57
【问题描述】:
如何使用方法语法从多个表中获取数据而不使用连接,而只使用 .where() 方法?
我正在针对 EF5 db 上下文进行选择,该上下文映射到这个遗留表结构,其中我有一个人员详细信息表和另一个表,该表同时引用自身以创建层次结构和人员详细信息表:
PersonSet
.Where(p => p.LastName.ToLower()=="surname")
.Join(SubsetSet, p => p.Id, ss => ss.SubsetLink, (p, ss) => new { PersonDetail = p, person = ss })
.Where(m => m.person.Frame=="a" && m.person.Purpose=="1")
.Join(SubsetSet, ss1 => ss1.person.Owner, person => person.SubsetLink, (ss1, ss2) => new { person = ss1, club = ss2 })
.Where(a => a.club.Frame=="b" && a.club.Purpose=="2")
.Join(SubsetSet, ss => ss.club.Owner, ss2 => ss2.SubsetLink, (ss, ss2) => new { club = ss, association = ss2 })
.Where(a => a.association.Frame=="b" && a.association.Purpose=="3")
.Join(SubsetSet, ss => ss.association.Owner, ss3 => ss3.SubsetLink, (ss, ss3) => new { association = ss, district = ss3})
.Where(d => d.district.Frame=="b" && d.district.Purpose=="4" && d.district.SubsetLink=="12345")
.Select(proj => new { proj.association.club.person, proj.association.club, proj.association, proj.district })
.OrderByDescending(a => a.association.club.person.phyperson.FirstName)
.Take(10).Dump();
上述查询至少在 LinqPad 中有效,但在我看来,如果我可以摆脱这些连接,则该语句可能看起来更好一些。现在我知道,就像在下面的 Albahari 示例中一样,这可以通过查询语法来完成。但是我找不到可以用方法语法说明这种情况的示例。我试图解决这个问题的方式当然可能是错误的,这就是为什么我找不到合适的例子。
在这里我发现了类似的东西,但无法在 LinQPad 中使用: Is multiple .Where() statements in LINQ a performance issue?
或者这个,解决方案再次出现在查询语法中: Cross Join with Where clause
或者 Albahari 的这个例子:(http://www.linqpad.net/WhyLINQBeatsSQL.aspx)
from p in db.Purchases
where p.Customer.Address.State == "WA" || p.Customer == null
where p.PurchaseItems.Sum (pi => pi.SaleAmount) > 1000
select p
【问题讨论】:
-
通常每个实体都有一个连接到另一个实体的属性,即在上面的 Albahari 示例中,
Purchase有一个Customer,它链接到购买该商品的特定客户。您的实体有这些吗? -
在 ALbahri 示例中是导航属性 Customer 和 PurchaseItems。如果您的实体具有导航属性,则不应使用 join 将它们与您的实体链接。
-
@NedStoyanov 啊,我只有这两个实体,没有在 edmx 中定义它们之间的关联。原始数据库没有关系。这两个表/实体之间的链接键字段类型不同。所以我无法建立关联。从我的示例代码中可以看出,自引用 SubsetSet 有五个相互引用的键(所有者到 SubsetLink)。所以我想没有连接就不能完成?
-
我会这么说,我看不出有任何其他方法
标签: c# asp.net linq lambda entity-framework-5