如何在 Linq Query 中应用自连接?
How to apply self join in Linq Query?
书籍Table
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 查询,它将 return 我的行对应于每个 gold if sil 供应商编号不存在。 vendor Id 的最后三位数字是该行中对应的 ASIN 列。
Ex- 对于 gold123 对应的 sil123 存在,因此行不会被 returned 但对于 gold678 和 gold980 对应的 sil 不存在。所以这些行将被 returned.
我尝试关注
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 goldWithoutCorrespondingSilver = from b1 in books
join b2 in books on b1.ASIN equals b2.ASIN
where b1.VendorId.Contains("gold")
group b2 by b1.VendorId into g
where !g.Any(x => x.VendorId.Contains("sil"))
select g.FirstOrDefault();
我所做的是-
- 已选择具有匹配 ASIN 的记录
- 按 VendorID 对它们进行分组
- 没有sil
的精选
这只是另一个谓词,"where a corresponding silver vendor doesn't exist":
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();
在许多情况下,这是一个成功的秘诀:使用您想要 return 的实体开始查询,并且只添加谓词。一般来说,连接不应该用于过滤,而只能用于收集相关数据,尽管在这种情况下应该使用导航属性,它隐式转换为 SQL 连接。
书籍Table
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 查询,它将 return 我的行对应于每个 gold if sil 供应商编号不存在。 vendor Id 的最后三位数字是该行中对应的 ASIN 列。
Ex- 对于 gold123 对应的 sil123 存在,因此行不会被 returned 但对于 gold678 和 gold980 对应的 sil 不存在。所以这些行将被 returned.
我尝试关注
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 goldWithoutCorrespondingSilver = from b1 in books
join b2 in books on b1.ASIN equals b2.ASIN
where b1.VendorId.Contains("gold")
group b2 by b1.VendorId into g
where !g.Any(x => x.VendorId.Contains("sil"))
select g.FirstOrDefault();
我所做的是-
- 已选择具有匹配 ASIN 的记录
- 按 VendorID 对它们进行分组
- 没有sil 的精选
这只是另一个谓词,"where a corresponding silver vendor doesn't exist":
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();
在许多情况下,这是一个成功的秘诀:使用您想要 return 的实体开始查询,并且只添加谓词。一般来说,连接不应该用于过滤,而只能用于收集相关数据,尽管在这种情况下应该使用导航属性,它隐式转换为 SQL 连接。