查询子集合 - 列表中包含的多数共同 ID
Query sub collection - majority mutual ids that contains in list
考虑以下列表:
List<long> listOfIDs = new List<long> { 1, 2, 3, 4 };
[(Product) 1 Pineapple - (Supplier) Fruit Inc / Marketplace Inc]>
[2 Strawberry - Fruit Inc]>
[3 Coke - Super Drinks Inc / Marketplace Inc]>
[4 Orange Juice - Super Drinks Inc]
db.Table.Where(a => a.SubTable.All(b => listOfIds.Contains(b.SubTableId)))
虽然我选择了产品 1 和 2,但我应该只有 Fruit Inc 作为供应商。当我将可口可乐加入我的列表时,我不想再看到任何供应商,因为没有供应商同时代表这 3 种产品。
预期产出情景:
已选产品:1、2
预期结果:Fruit Inc
1、3
市场公司
1、2、3
空。
1、3、4
空。
3、4
超级饮品公司
我想我终于明白了问题所在。
所以你有两个实体 many-to-many
关系如下:
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Supplier> Suppliers { get; set; }
}
public class Supplier
{
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
给定一个包含产品 ID 的列表,您想要获取提供列表中所有产品的供应商列表。
至少有两种方法可以做到这一点:
List<long> productIds = ...;
(A) 与您的尝试类似,但交换 All
和 Contains
的角色:
var suppliers = db.Suppliers
.Where(s => productIds.All(id => s.Products.Any(p => p.Id == id)))
.ToList();
或者如果你更喜欢Contains
(两者都生成一个相同的SQL):
var suppliers = db.Suppliers
.Where(s => productIds.All(id => s.Products.Select(p => p.Id).Contains(id)))
.ToList();
(B) 计算匹配数:
var suppliers = db.Suppliers
.Where(s => s.Products.Count(p => productIds.Contains(p.Id)) == productIds.Count)
.ToList();
我不能说哪一个在性能方面更好,但它们都产生了预期的结果并且得到了 LINQ to Entities 的支持。
您的问题取决于这样一个事实,即与您的过滤器列表中包含的产品相比,给定供应商可以拥有更多与其相关的产品。
您应该通过交换数据源容器来解决此问题,以便在您的 linq 查询中测试您的条件:
db.Table.Where(a => listOfIds.All(b => a.SubTable.Contains(b)))
您也可以通过这种方式阅读此查询:
get all the suppliers (a
records) for which is true that all
products (b
elements) contained in listOfIds
must be also
contained in products list related to each supplier (a.SubTable
).
考虑以下列表:
List<long> listOfIDs = new List<long> { 1, 2, 3, 4 };
[(Product) 1 Pineapple - (Supplier) Fruit Inc / Marketplace Inc]>
[2 Strawberry - Fruit Inc]>
[3 Coke - Super Drinks Inc / Marketplace Inc]>
[4 Orange Juice - Super Drinks Inc]
db.Table.Where(a => a.SubTable.All(b => listOfIds.Contains(b.SubTableId)))
虽然我选择了产品 1 和 2,但我应该只有 Fruit Inc 作为供应商。当我将可口可乐加入我的列表时,我不想再看到任何供应商,因为没有供应商同时代表这 3 种产品。
预期产出情景:
已选产品:1、2 预期结果:Fruit Inc
1、3 市场公司
1、2、3 空。
1、3、4 空。
3、4 超级饮品公司
我想我终于明白了问题所在。
所以你有两个实体 many-to-many
关系如下:
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Supplier> Suppliers { get; set; }
}
public class Supplier
{
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
给定一个包含产品 ID 的列表,您想要获取提供列表中所有产品的供应商列表。
至少有两种方法可以做到这一点:
List<long> productIds = ...;
(A) 与您的尝试类似,但交换 All
和 Contains
的角色:
var suppliers = db.Suppliers
.Where(s => productIds.All(id => s.Products.Any(p => p.Id == id)))
.ToList();
或者如果你更喜欢Contains
(两者都生成一个相同的SQL):
var suppliers = db.Suppliers
.Where(s => productIds.All(id => s.Products.Select(p => p.Id).Contains(id)))
.ToList();
(B) 计算匹配数:
var suppliers = db.Suppliers
.Where(s => s.Products.Count(p => productIds.Contains(p.Id)) == productIds.Count)
.ToList();
我不能说哪一个在性能方面更好,但它们都产生了预期的结果并且得到了 LINQ to Entities 的支持。
您的问题取决于这样一个事实,即与您的过滤器列表中包含的产品相比,给定供应商可以拥有更多与其相关的产品。
您应该通过交换数据源容器来解决此问题,以便在您的 linq 查询中测试您的条件:
db.Table.Where(a => listOfIds.All(b => a.SubTable.Contains(b)))
您也可以通过这种方式阅读此查询:
get all the suppliers (
a
records) for which is true that all products (b
elements) contained inlistOfIds
must be also contained in products list related to each supplier (a.SubTable
).