Linq查询与几个左连接生成很少的查询

时间:2018-05-31 05:46:22

标签: c# asp.net linq left-join entity-framework-core

我尝试使用实体框架Core在asp核心2上用linq编写查询并且所有ok,查询返回正确的结果,但非常慢。

var Query1 =
        from demand in _prabacontext.Demand
        join demandspec in _prabacontext.DemandSpec on demand.Id equals demandspec.DemandId into demandspecGroup
        join manager in _prabacontext.Manager on demand.ManagerId equals manager.Id into managerGroup
        from m in managerGroup.DefaultIfEmpty()
        join contractor in _prabacontext.Contractor on demand.ContractorId equals contractor.Id into contractorGroup
        from c in contractorGroup.DefaultIfEmpty()
        join company in _prabacontext.Company on c.CompanyId equals company.Id into companyGroup
        from cm in companyGroup.DefaultIfEmpty()
    where demand.RegDate >= Convert.ToDateTime("2018-01-01T00:00:00")
        select new
        {
            demand.Id,
            demand.Id1,
            RegDate = demand.RegDate.ToString("yyyy-MM-dd"),
            demand.IsLgot,
            demand.ContractorId,
            demand.DocNumber,
            demand.DocStatus,
            demand.ManagerId,
            demand.Remark,
            StrSum = demandspecGroup.Sum(x => (decimal?)(x.Price * x.Quantity)) ?? 0,
            ContractorName = cm.Name,
            ManagerName = m.Name1//+' '+m.Name2+' '+m.Name3
        };

在调试器日志中,此linq查询转换为此SQL语句:

SELECT 
    "demand"."_ID" AS "Id0", 
    "demand"."Contractor_ID" AS "ContractorId", 
    "demand"."DocNumber", 
    "demand"."DocStatus", 
    "demand"."ID" AS "Id1", 
    "demand"."Insert_Date", 
    "demand"."Insert_User", 
    "demand"."IsLgot", 
    "demand"."IsTender", 
    "demand"."last_updated", 
    "demand"."Manager_ID" AS "ManagerId", 
    "demand"."RegDate", 
    "demand"."Remark" AS "Remark0", 
    "demandspec"."_ID", 
    "demandspec"."Commerc_ID", 
    "demandspec"."DeliveryDate", 
    "demandspec"."_Demand_ID", 
    "demandspec"."Demand_ID", 
    "demandspec"."FinType_ID", 
    "demandspec"."Goods2_ID", 
    "demandspec"."Goods_ID", 
    "demandspec"."GoodsUnion_ID", 
    "demandspec"."ID", 
    "demandspec"."last_updated", 
    "demandspec"."Price", 
    "demandspec"."Quantity", 
    "demandspec"."Remainder", 
    "demandspec"."Remark", 
    "demandspec"."Reserv"
FROM
    "Demand" AS "demand"
LEFT JOIN 
    "Demand_Spec" AS "demandspec" ON "demand"."_ID" = "demandspec"."_Demand_ID"
ORDER BY 
    "Id0"

SELECT "manager"."id", "manager"."name1"
FROM "manager" AS "manager"

SELECT "contractor"."id", "contractor"."company_id"
FROM "maxim"."contractor" AS "contractor"

SELECT "company"."id", "company"."name"
FROM "maxim"."company" AS "company"`

它从查询返回数据并以编程方式连接输出数据。但这张桌子非常大。我知道我可以直接编写SQL查询,但我想使用linq。

如何编写Linq查询,哪些内容转换为带有少量左连接的SQL查询?

加了:

在调试日志中,我找到了这样的字符串:

  

LINQ表达式' DefaultIfEmpty()'无法翻译,将在本地进行评估

查询中的每个表。如果没有这种结构我怎么能重写我的查询?

1 个答案:

答案 0 :(得分:0)

  

其中demand.RegDate> = Convert.ToDateTime(" 2018-01-01T00:00:00")

这似乎在TSQL输出中缺失,因此必须在本地进行评估。如果在本地评估,则会加载整个需求表,这就是查询运行缓慢的原因。

此外,如果您设置了导航属性,那么您不需要编写这些连接。

以下是我将如何编写相同的查询:

DateTime regDate = Convert.ToDateTime("2018-01-01T00:00:00");

var query1 =
    from demand in _prabacontext.Demand
    where regDate <= demand.RegDate
    let demandSpecs = demand.DemandSpecs
    let manager = demand.Manager
    let company = demand.Contractor.Company
    select new
    {
        demand.Id,
        demand.Id1,
        RegDate = demand.RegDate.ToString("yyyy-MM-dd"),
        demand.IsLgot,
        demand.ContractorId,
        demand.DocNumber,
        demand.DocStatus,
        demand.ManagerId,
        demand.Remark,
        StrSum = demandSpecs.Sum(x => (decimal?)(x.Price * x.Quantity)) ?? 0,
        ContractorName = company.Name,
        ManagerName = manager.Name1//+' '+manager.Name2+' '+manager.Name3
    };