c# - 如何在 Linq 查询中应用自连接?

标签 c# linq nhibernate linq-to-sql

图书表

Id  VendorId   ASIN   Price
--  --------   ----   ------
 1   gold123    123     10
 2   sil123     123     11
 3   gold456    456     15
 4   gold678    678     12
 5   sil456     456     12
 6   gold980    980     12

我想编写一个 linq 查询,如果 sil 供应商 ID 不存在,它将返回与每个 gold 对应的行。供应商 ID 的最后三位是该行中相应的 ASIN 列。

Ex-对于gold123,对应的sil123存在,因此不会返回该行,但对于gold678和gold980,对应的sil不存在。因此这些行将被返回。

我尝试遵循

     var gold = _repository.Query<Books>().Where(x => 
                  x.VendorId.Contains("gold"))
                 .OrderBy(x => x.Id).Skip(0).Take(500).ToList();

    var asinsForGold = gold.Select(x => x.ASIN).ToList();



  var correspondingSilver = _repository.Query<Books>().Where(x => 
                            x.VendorId.Contains("sil") 
                           && asinsForGold.Contains(x.ASIN)).ToList();

var correspondingSilverAsins = correspondingSilver.Select(x => x.ASIN).ToList();

var goldWithoutCorrespondingSilver = gold.Where(x => 
                                !correspondingSilverAsins.Contains(x.ASIN));

我们能否应用自连接或更好的方法来仅在一个查询中获取结果,而不是两个查询和其他几个列表语句。

最佳答案

这只是另一个谓词,“相应的白银供应商不存在”:

var goldWoSilver = _repository.Query<Books>()
    .Where(x => x.VendorId.Contains("gold"))
    .Where(x => !_repository.Query<Books>()
        .Any(s => s.ASIN == x.ASIN
               && s.VendorId.Contains("sil"))
    .OrderBy(x => x.Id).Skip(0).Take(500).ToList();

在许多情况下,这是一个成功的秘诀:使用要返回的实体启动查询并仅添加谓词。一般来说,联接不应用于过滤,而只能用于收集相关数据,尽管在这种情况下应使用隐式转换为 SQL 联接的导航属性。

关于c# - 如何在 Linq 查询中应用自连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56794013/

相关文章:

c# - 返回 linq 查询的结果,但修改了一个值

c# - 将两个 Lambda/Linq 查询添加在一起

c# - 结合序列化和语法解析的方法?

linq - ".OrderBy(p => p.Id)"和 "orderby p.Id ascending"之间的区别

c# - 为 IQueryable<T> 生成表达式

c# - NHibernate 如何查询 IList<string> 属性?

asp.net - 当使用 NHibernate 和每个请求的工作单元时,在什么情况下每个请求使用多个事务会有好处?

c# - 如何在 .NET 应用程序中松耦合数据库列?

c# - 更好的 Dispose 方法(通过 ComponentModel.IContainer ??)

c# - 如何检查 Stack<T> 是否为空