具有内部联接的实体框架复杂查询

时间:2016-12-14 23:51:01

标签: c# entity-framework linq

我想使用Entity Framework(Code First)执行复杂查询。

我知道它可以由LINQ完成,但是为复杂数据和内部连接编写LINQ查询的最佳方法是什么?

我想执行以下查询:

var v = from m in WebAppDbContext.UserSessionTokens
                from c in WebAppDbContext.Companies.Include(a => a.SecurityGroups)
                from n in WebAppDbContext.SecurityGroups.Include(x => x.Members)
                where m.TokenString == userTokenString &&
                n.Members.Contains(m.User) &&
                c.SecurityGroups.Contains(n)
                select c;

这是最好的方法吗?

此查询是否从db获取任何完整的记录列表,然后在此列表中执行过滤? (可能是巨大的名单)

最重要的是:它是否多次查询数据库?

2 个答案:

答案 0 :(得分:2)

在我看来,基于我自己的经验,谈论性能,尤其是加入数据集时,在SQL中编写它时速度会更快。但是既然你先使用了代码,那么它就不是一种选择。要回答您的问题,您的查询将不会多次查询数据库(您可以尝试调试并查看VS中的事件日志)。 EF会将您的查询转换为SQL语句并执行它。

答案 1 :(得分:1)

TL:DR;不要对机器人进行微观管理。让他们做他们的事情,99%的时间你会没事的。 Linq并没有真正公开微观管理底层数据查询的方法,无论如何,它的整个目的是成为一个抽象层。

根据我的经验,Linq提供商非常聪明地将有效的Linq语法转换为"非常好" SQL。您的查询看起来像是所有内部联接,并且这些都应该位于每个表的主索引/外键上,因此它会提供一些相当不错的东西。

如果这还不足以缓解您的担忧,我建议:

  1. 使用SQL Trace查看正在向数据库显示的实际查询。我敢打赌它并不像公司加入SecurityGroups那样简单加入会员加入UserTokens,但它可能等同于它。
  2. 如果这成为实际的性能问题,只关心优化。
  3. 如果它确实成为性能问题,请考虑重构问题空间。看起来您正试图通过浏览其他三个表来从UserToken获取公司记录。是否可以直接关联用户和公司,而不是通过安全模型? (请原谅我对你的问题空间的完全无知,我只是说"从另一个角度看问题?")
  4. 简而言之,听起来你正在燃烧脑循环试图过早地优化某些东西。现在,考虑 是否存在性能问题是合理的,代码的这一部分可能是负责任的,但只有在您执行此查询时才会注意到这一点 >很多。基于来自安全令牌,我猜你每次会话都要这样做一次,以获取当前用户的上下文信息。在这种情况下,问题通常不是Linq,而是您解决查找公司信息问题的方法。你可以缓存结果吗?