如何将2个Linq查询合并为1个?

时间:2017-11-21 11:49:31

标签: c# entity-framework linq

参数 - (字符串供应商)

var supplierID = db.SupplierTable
            .Where(m => m.SupplierName.Trim().ToLower() == Supplier.Trim().ToLower())
            .Select(m => m.SupplierID).First();

var supplierREFs = db.ProductSuppliers
            .Where(m => m.SupplierID == supplierID)
            .Select(m => m.SupplierRef);

可以将上述2个查询合并为1个查询吗?

3 个答案:

答案 0 :(得分:2)

当然,您需要一个子查询:

Supplier = Supplier.Trim();  // do this once and not in the query

var supplierREFs = db.ProductSuppliers
    .Where(m => db.SupplierTable
        .Where(s => m.SupplierID == s.SupplierID)
        .Any(s => String.Equals(s.SupplierName.Trim(), Supplier, StringComparison.CurrentCultureIgnoreCase))
     )
    .Select(m => m.SupplierRef);

此查询会将ProductSupplier匹配给定SupplierName的每个Supplier(忽略大小写)。然后它返回SupplierRef

旁注:如果您不在数据库中存储带有前导/尾随空格的SupplierNames,则不应与s.SupplierName.Trim()进行比较,而应与s.SupplierName进行比较。

答案 1 :(得分:0)

你可以加入两个实体,比如;

Supplier = Supplier.Trim().ToLower();

var supplierREFs = (from st in db.SupplierTable
                                join sr in supplierREFs on st.SupplierID equals sr.SupplierID
                                where 
                                st.SupplierName.Trim().ToLower() == Supplier
                                select sr)

答案 2 :(得分:0)

显然,您的SupplierTable中的供应商商品与ProductSuppliersTable中的ProductSupplier商品之间存在一对多的关系:

每个供应商都有零个或多个产品供应商,每个产品供应商都属于一个供应商。

如果您已配置one-to-many relationship according to the default entity framework conventions,则您的课程类似于以下内容:

class Supplier
{
    public int Id {get; set;}
    // Every Supplier has zero or more ProductSupplierTables:
    public virtual ICollection<ProductSuppierTable> ProductSupplierTables {get; set;}

    public string SupplierName {get; set;}
    ...
}

class ProductSupplier
{
    public int Id {get; set;}
    // every ProductSupplier belongs to exactly one Supplier using foreign key
    public virtual Supplier Supplier {get; set;}
    public int SupplierId {get; set;}

    public string SupplierRef {get; set;}
    ...
}

可能有些标识符名称不同,但理念很明确:您的供应商需要产品供应商的虚拟ICollection,而您的ProductSupplier需要供应商的外键以及虚拟供应商。

一旦您正确完成此操作,实体框架就会知道主键和外键并为您创建正确的表。

好消息是你的DbContext和你的DbSets知道这种一对多的关系。每当您需要供应商使用其ProductSuppliers时,您就不需要在外键上执行连接。您可以改为使用ICollection。

为自己改写你想要的东西。

  

我有供应商的名称,我想要第一个供应商项目   我的SupplierTable具有与此相等的Trimmed LowerCase名称   name,以及供应商提供的所有SupplierRef   ProductSuppliers。

using (var dbContext = new MyDbContext())
{
    string supplierName = Supplier.Trim().ToLower()
    dbContext.Suppliers
       .Where(supplier => String.ToLower(supplier.SupplierName) == supplierName)
       .Select(supplier => new
       {   // to improve performance: select only the properties you'll use
           SupplierId = supplier.Id,
           ...

           // select also all the SupplierRefs from its ProductSuppliers:
           SupplierRefs = supplier.ProductSupplier
               .Select(productSupplier => productSupplier.SupplierRef)
               .ToList(),
        })
        // I only want the First (or default) of these suppliers:
        .FirstOrDefault();
    }
}

实体框架知道您的一对多,以及使用哪个外键。实体框架将进行正确的连接并为您选择。