Lambda表达式代替左联接

时间:2018-07-27 04:43:23

标签: c# .net lambda

我尝试将T-SQL转换为lambda表达式,但是遇到了问题。数据不正确。

这是我的查询

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        GlobalConfiguration.Configure(WebApiConfig.Register);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterOpenAuth();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}

这是我的lambda表达式

SELECT A.* 
FROM 
    (SELECT UserId, MIN(ID) AS ID 
     FROM FingerMachineUsers  
     GROUP BY UserId ) A
LEFT OUTER JOIN 
    FingerTimeSheets B ON A.ID = B.UserNo 
                       AND B.DayOfCheck = '2018-08-02 00:00:00.000'
WHERE 
    B.UserNo IS NULL

返回的数据不正确。

1 个答案:

答案 0 :(得分:0)

linq查询应为:

DateTime date = DateTime.Today;

var innerQuery = from x in db.FingerMachineUsers
                    group x.UserId by x.UserId into y
                    select new { UserId = y.Key, ID = y.Min() };

var query = from x in innerQuery
            join y in db.FingerTimeSheets on x.ID equals y.UserNo into z
            from y in z.Where(a => a.DayOfCheck == date).DefaultIfEmpty()
            where y == null || y.UserNo == null
            select x;

查询大致等于:

SELECT 
    [GroupBy1].[K1] AS [UserId], 
    [GroupBy1].[A1] AS [C1]
    FROM   (SELECT 
        [Extent1].[UserId] AS [K1], 
        MIN([Extent1].[UserId]) AS [A1]
        FROM [dbo].[FingerMachineUsers] AS [Extent1]
        GROUP BY [Extent1].[UserId] ) AS [GroupBy1]
    LEFT OUTER JOIN [dbo].[FingerTimeSheets] AS [Extent2] ON (([GroupBy1].[A1] = [Extent2].[UserNo]) OR (([GroupBy1].[A1] IS NULL) AND ([Extent2].[UserNo] IS NULL))) AND ([Extent2].[DayOfCheck] = @p__linq__0)
    WHERE [Extent2].[TimeSheetId] IS NULL OR [Extent2].[UserNo] IS NULL

(其中TimeSheetIdFingerTimeSheets的主键)

关于FingerTimeSheets.UserNo的可空性和B.UserNo IS NULL的含义,有一些开放的观点。 FingerTimeSheets.UserNo是否可以为空?然后查询是正确的。如果FingerTimeSheets.UserNo不可为空,则将where更改为:

where y == null

另一个需要解决的小问题是FingerMachineUsers.ID是否都可以为空,而FingerTimeSheets.UserNo是否可以为空。将模式from y in z.Where()更改为:

from y in z.Where(a => UserNo != null && a.DayOfCheck == date).DefaultIfEmpty()