繁体   English   中英

如何使用Lambda表达式从LINQ中的左联接中提取max(property)

[英]How to extract max(property) from left join in LINQ with lambda expression

我有四张桌子:

  • CL_ProductType
  • CL_InsuranceProduct
  • PR_Product
  • PR_ProductInsuranceProduct(PR_Product和CL_InsuranceProduct的汇总表)

我需要左连接PR_ProductInsuranceProduct,并且已经使用SelectMany()选择器完成了。 问题是此查询具有groupBy方法,我需要提取max(ID_ProductInsuranceProduct)。

我的问题是 :如何在.SelectMany()中提取ID_ProductInsuranceProduct的较高值?

有效的SQL:

select p.ID_Product,p.Name, p.Code, p.InProduction, MAX(pip.ID_ProductInsuranceProduct)
from PR_Product p
join CL_ProductType pt  ON p.ID_ProductType = pt.ID_ProductType
left join PR_ProductInsuranceProduct pip ON p.ID_Product = pip.ID_Product
join CL_InsuranceProduct ip ON pip.ID_InsuranceProduct = ip.ID_InsuranceProduct
GROUP BY p.ID_Product,p.Name, p.Code, p.InProduction

我在C#和LINQ Lambda中的代码:

 var query = DBContext.PR_Product
            .Where(m => m.Active)
            .Where(nameFilter)
            .Where(activationDateFilter)
            .Where(closureDateFilter)
            .Where(productTypeFilter)
            .Where(subgroupFilter)
            .Where(inproductionFilter)
            .Where(answerFilter)
            .Where(insuranceProductFilter)
            .Where(excludePidsFilter)
            .Join(DBContext.CL_ProductType, p => p.ID_ProductType, pt => pt.ID_ProductType,
                (p, pt) => new { p, pt = pt.Name })
            .GroupJoin(DBContext.PR_ProductInsuranceProduct,
                p => p.p.ID_Product,
                pip => pip.ID_Product,
                (p1, pip) => new { Products = p1, ProductInsuranceProduct = pip })
                .SelectMany
                (
                    x => x.ProductInsuranceProduct.DefaultIfEmpty(), 
                    (x, y) => new
                    {
                        x.Products.p.ID_Product,
                        x.Products.p.Name,
                        x.Products.p.Code,
                        x.Products.p.ActivationDate,
                        x.Products.p.ClosureDate,
                        x.Products.pt,
                        x.Products.p.InProduction,
                        //Here I want to fill in to my custom property max for ID_ProductInsuranceProduct, MaxId is a custom property in a model
                        x.Products.p.MaxId = x.ProductInsuranceProduct.Max(pip => pip.ID_ProductInsuranceProduct)
                    })
                .GroupBy(x =>
                  new
                  {
                      x.ID_Product,
                      x.Name,
                      x.Code,
                      x.ActivationDate,
                      x.ClosureDate,
                      x.pt,
                      x.InProduction,
                  });

我假设,因为它是一个SelectMany,所以我的代码将“拼合”数据返回到一个表中,因此,我的方法Max,其输入是错误的,因为它不是集合?

我可以只用.Select()离开linq吗?

执行查询时,代码的延续:

 count = query.Count();

        var list = query
            .OrderBy(x => x.FirstOrDefault().Code)
            .DoPaging(pageSize, pageIndex)
            .ToList();

        List<PR_Product> products =
            (from m in list
             select new PR_Product
             {
                 ID_Product = m.Key.ID_Product,
                 Name = m.Key.Name,
                 Code = m.Key.Code,
                 ActivationDate = m.Key.ActivationDate,
                 ClosureDate = m.Key.ClosureDate,
                 ActivationDateString = m.Key.ActivationDate.ToString("d", new CultureInfo(DALParams.LCID, false)),
                 ClosureDateString = m.Key.ClosureDate.ToString("d", new CultureInfo(DALParams.LCID, false)),
                 ProductType = m.Key.pt,
                 InProduction = m.Key.InProduction
                 //MaxId = implemention...
             }).ToList();

给定以下对象:

public class PR_Product
{
    public int ID_Product { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public bool InProduction { get; set; }
}

public class PR_ProductInsuranceProduct
{
    public int ID_ProductInsuranceProduct { get; set; }
    public int ID_Product { get; set; }

}

我已在内存集合中创建演示了如何使用lambda表达式从LINQ中的左联接中提取max(property):

        var product = new List<PR_Product>
        {
            new PR_Product { ID_Product = 1, Name = "TestName1", Code = "TestCode1", InProduction = true },
            new PR_Product { ID_Product = 2, Name = "TestName2", Code = "TestCode3", InProduction = true },
            new PR_Product { ID_Product = 3, Name = "TestName3", Code = "TestCode3", InProduction = true }
        };

        var productInsurance = new List<PR_ProductInsuranceProduct>
        {
            new PR_ProductInsuranceProduct { ID_ProductInsuranceProduct = 111, ID_Product = 1 },
            new PR_ProductInsuranceProduct { ID_ProductInsuranceProduct = 222, ID_Product = 1 },
            new PR_ProductInsuranceProduct { ID_ProductInsuranceProduct = 333, ID_Product = 3 },
        };

        var result = product
            .GroupJoin(productInsurance,
                prProduct => prProduct.ID_Product,
                insuranceProduct => insuranceProduct.ID_Product,
                (prProduct, insuranceProduct) => new { prProduct, insuranceProduct })
            .SelectMany(arg => arg.insuranceProduct.DefaultIfEmpty(), (prProduct, insuranceProducts) => new { prProduct })
            .GroupBy(arg => new { arg.prProduct.prProduct.ID_Product, arg.prProduct.prProduct.Name, arg.prProduct.prProduct.Code, arg.prProduct.prProduct.InProduction})
            .Select(grouping => new
            {
                grouping.Key.ID_Product,
                grouping.Key.Name,
                grouping.Key.Code,
                Max_ID_ProductInsuranceProduct = grouping.FirstOrDefault()?.prProduct.insuranceProduct.DefaultIfEmpty().Max(insuranceProduct => insuranceProduct?.ID_ProductInsuranceProduct)
            });


        Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM