【问题标题】:Best way to filter query by navigation property(child objects) in LINQ to SQL在 LINQ to SQL 中按导航属性(子对象)过滤查询的最佳方法
【发布时间】:2017-02-07 06:30:26
【问题描述】:

我有两个选项来过滤我的查询:

var users = query.Select(x => x.User).FindUsers(searchString);
query = query.Where(x => users.Contains(x.User));

var userIds = query.Select(x => x.User).FindUsers(searchString).Select(x => x.Id);
query = query.Where(x => userIds.Contains(x.UserId));

FindUsers分机说明:

static IQueryable<User> FindUsers(this IQueryable<User> query, string searchString);

那么我最终会在 SQL 中得到什么?这两个请求中哪一个对性能更好?
如果有人有其他建议,请写在答案中。

提前致谢!

【问题讨论】:

    标签: c# performance entity-framework linq linq-to-sql


    【解决方案1】:

    这两个查询在 EF v6 或更高版本中是相似的;包含条件将被翻译为 Sql EXISTS

    看看下面的代码:

     using (var dbContext = new DbContextTest("DatabaseConnectionString"))
      {
        var users = dbContext.Users.Select(u => u).Where(x => x.UserId > 0);
        var query = dbContext.Users.Where(x => users.Contains(x));
        Console.WriteLine(query.ToList());
      }
    
      using (var dbContext = new DbContextTest("DatabaseConnectionString"))
      {
        var ids = dbContext.Users.Select(u => u.UserId).Where(x => x > 0);
        var query = dbContext.Users.Where(x => ids.Contains(x.UserId));
        Console.WriteLine(query.ToList());
      }
    

    输出的 Sql 查询完全相同(您可以使用分析器或 EF 记录器来查看)。有一件事可能很重要,只选择 Id 会更灵活地实现和缓存。

    提示: 如果在 Ids 查询中添加 ToList() dbContext.Users.Select(u => u.UserId).Where(x => x > 0).ToList();那么此修复将改善您的结果性能。下一个选择查询将使用 SQL“IN”而不是“EXISTS”进行翻译!看看这个链接Difference between EXISTS and IN in SQL?,你可以决定什么更适合你。

    注意: ToList() 将实现 Id,这意味着您将使用另一个接口,然后是 IQueryable!

    【讨论】:

    • 感谢您的回复!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2010-10-14
    相关资源
    最近更新 更多