查询子集合 - 列表中包含的多数共同 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) 与您的尝试类似,但交换 AllContains 的角色:

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).