繁体   English   中英

Linq to SQL 对连接的帮助

[英]Linq to SQL assistance with joins

请您帮我将以下 SQL 查询翻译成 LINQ 主要是我遇到问题的连接。 结果将是执行的 LINQ to SQL 代码。

非常感谢

SELECT * FROM   unit INNER JOIN   

 unit_measurement_total ON unit.prime_measurement_uri = unit_measurement_total.uri RIGHT OUTER JOIN
   property_expense_schedule 
        INNER JOIN
     unit_apportionment ON property_expense_schedule.uri = unit_apportionment.property_expense_schedule_uri 
        INNER JOIN
      unit_apportionment_date ON unit_apportionment.uri = unit_apportionment_date.unit_apportionment_uri ON 
     unit_measurement_total.property_ref = unit_apportionment.property_ref
        WHERE (property_expense_schedule.property_ref = ...) 

这是我目前拥有的 LINQ,但它生成的结果与 SQL 查询不同。 所以我在连接和正确的外部连接上出错了。

 var query = (from units in context.units
                 join unitmestot in context.unit_measurement_total on units.prime_measurement_uri equals unitmestot.uri
                 from pes in context.property_expense_schedule
                 join unitapp in context.unit_apportionment on new { A = pes.uri, B = unitmestot.property_ref, C = unitmestot.unit_ref } equals new { A = unitapp.property_expense_schedule_uri, B = unitapp.property_ref, C = unitapp.unit_ref}
                 join unitappdate in context.unit_apportionment_date on unitapp.uri equals unitappdate.unit_apportionment_uri
                 select new Apportionment()
                 {
                     PropertyRef = units.property_ref.ToString(),
                     ScheduleName = pes.name,
                     ScheduleRef = pes.@ref.ToString(),
                     PropertyExpenseScheduleUri = pes.uri,
                     UnitRef = units.@ref.ToString(),
                     UnitName = "(" + units.@ref.ToString() + ")" + units.name,
                     ObseleteUnit = units.obsolete_unit,
                     ApportionmentPercentage = unitappdate.apportionment_percentage,
                     ToDate = unitappdate.to_date,
                     MeasurementBasis = unitmestot.measurement_basis,
                     MeasuredIn = unitmestot.measured_in,
                     MeasurementImperialTotal = unitmestot.measurement_imperial_total,
                     MeasurementMetricTotal = unitmestot.measurement_metric_total

                 }).Where(filter);

您提供的最新代码生成以下 SQL 并返回 0 行。

  SELECT     [Extent1].[uri] AS [uri],     CASE WHEN ([Join3].[property_ref1] IS NULL) THEN N'' ELSE  CAST( [Join3].[property_ref1] AS nvarchar(max)) END AS [C1],     [Extent3].[name] AS [name],      CAST( [Extent3].[ref] AS nvarchar(max)) AS [C2],     [Extent3].[uri] AS [uri1],     CASE WHEN ([Join3].[ref] IS NULL) THEN N'' ELSE  CAST( [Join3].[ref] AS nvarchar(max)) END AS [C3],     N'(' + CASE WHEN (CASE WHEN ([Join3].[ref] IS NULL) THEN N'' ELSE  CAST( [Join3].[ref] AS nvarchar(max)) END IS NULL) THEN N'' WHEN ([Join3].[ref] IS NULL) THEN N'' ELSE  CAST( [Join3].[ref] AS nvarchar(max)) END + N')' + CASE WHEN ([Join3].[name] IS NULL) THEN N'' ELSE [Join3].[name] END AS [C4],     [Join3].[obsolete_unit] AS [obsolete_unit],     [Extent2].[apportionment_percentage] AS [apportionment_percentage],     [Extent2].[to_date] AS [to_date],     CASE WHEN ([Join3].[measurement_basis] IS NULL) THEN N'' ELSE [Join3].[measurement_basis] END AS [C5],     CASE WHEN ([Join3].[measured_in] IS NULL) THEN N'' ELSE [Join3].[measured_in] END AS [C6],     [Join3].[measurement_imperial_total] AS [measurement_imperial_total],     [Join3].[measurement_metric_total] AS [measurement_metric_total]    FROM    [tramps].[unit_apportionment] AS [Extent1]    INNER JOIN [tramps].[unit_apportionment_date] AS [Extent2] ON [Extent1].[uri] = [Extent2].[unit_apportionment_uri]    INNER JOIN [tramps].[property_expense_schedule] AS [Extent3] ON [Extent1].[property_expense_schedule_uri] = [Extent3].[uri]    LEFT OUTER JOIN  (SELECT [Extent4].[property_ref] AS [property_ref2], [Extent4].[measurement_basis] AS [measurement_basis], [Extent4].[measured_in] AS [measured_in], [Extent4].[measurement_imperial_total] AS [measurement_imperial_total], [Extent4].[measurement_metric_total] AS [measurement_metric_total], [Extent5].[property_ref] AS [property_ref1], [Extent5].[ref] AS [ref], [Extent5].[name] AS [name], [Extent5].[obsolete_unit] AS [obsolete_unit]        FROM  [tramps].[unit_measurement_total] AS [Extent4]        INNER JOIN [tramps].[unit] AS [Extent5] ON [Extent4].[uri] = [Extent5].[prime_measurement_uri] ) AS [Join3] ON [Extent1].[property_ref] = [Join3].[property_ref2]    WHERE (N'101329' = (CASE WHEN ([Join3].[property_ref1] IS NULL) THEN N'' ELSE  CAST( [Join3].[property_ref1] AS nvarchar(max)) END)) AND ( NOT (('Y' = [Join3].[obsolete_unit]) AND ([Join3].[obsolete_unit] IS NOT NULL)))

LINQ 不支持Right Outer Join ,因此应该通过交换左右部分并执行Left Outer Join来模拟(这不太自然,但至少是 known- join 子句(C# 参考)中的模式)。

话虽如此,我认为等效的 LINQ 查询应该是这样的:

from unitapp in context.unit_apportionment
    join unitappdate in context.unit_apportionment_date on unitapp.uri equals unitappdate.unit_apportionment_uri
    join pes in context.property_expense_schedule on unitapp.property_expense_schedule_uri equals pes.uri
    join unitmestot in context.unit_measurement_total on unitapp.property_ref equals unitmestot.property_ref
        into unitapp_unitmesstot from unitmestot in unitapp_unitmesstot.DefaultIfEmpty() // Left Outer Join
    join units in context.units on unitmestot.uri equals units.prime_measurement_uri
       select new Apportionment()
       {
           // ...
       }

编辑:看起来 EF 在左外连接之后为内连接生成附加条件,这导致与原始 SQL 查询的差异。 在这种情况下,您可以尝试将正确的部分分组到子查询中以尝试更改连接顺序:

    from unitapp in context.unit_apportionment
    join unitappdate in context.unit_apportionment_date on unitapp.uri equals unitappdate.unit_apportionment_uri
    join pes in context.property_expense_schedule on unitapp.property_expense_schedule_uri equals pes.uri
    join right in (
        from unitmestot in context.unit_measurement_total
        join units in context.units on unitmestot.uri equals units.prime_measurement_uri
        select new { unitmestot, units } 
    ) on unitapp.property_ref equals right.unitmestot.property_ref
    into outerJoin from right in outerJoin.DefaultIfEmpty() // Left Outer Join
    let unitmestot = right.unitmestot
    let units = right.units
    select new Apportionment()
    {
       // ...
    }

暂无
暂无

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

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