简体   繁体   English

通过过滤将SQL连接转换为带有EF的LINQ

[英]Converting a SQL join into LINQ with EF with filtering

I'm learning Entity Framework and attempting to convert an existing SQL query to a LINQ query, but struggling to convert it. 我正在学习Entity Framework,并尝试将现有的SQL查询转换为LINQ查询,但努力将其转换。

SELECT taskItems.Description,taskItemResponses.IsCompleted,TaskItemResponses.userId,TaskItemResponses.Notes 
FROM TaskLists
LEFT JOIN TaskItems ON TaskLists.TaskListId = TaskItems.TaskListId
LEFT JOIN TaskItemResponses ON TaskItemResponses.TaskItemId = TaskItems.TaskItemId 
AND TaskItemResponses.UserId = '1'

This works fine for me, it brings back the following data, always showing the list of Tasks, and if a user has responded to any of them, if they've completed it and what notes they've added. 这对我来说效果很好,它会带回以下数据,始终显示任务列表,以及用户是否对其中任何一个做出了响应,是否完成了任务以及添加了哪些注释。

Description  IsCompleted   userId  Notes
Task A       NULL          NULL    NULL
Task B       NULL          NULL    NULL
Task C       NULL          NULL    NULL
Task D       1             1       I've done this now.
Task E       NULL          NULL    NULL

But when I'm trying to convert this to a LINQ query within C# I can't figure out the syntax, so far i've got 但是当我试图将其转换为C#中的LINQ查询时,我无法弄清楚语法,到目前为止,我已经

var query = from t in DbContext.TaskList
join ti in DbContext.TaskItem on t.TaskListId equals ti.TaskListId
join tr in DbContext.TaskItemResponse on ti.TaskItemId equals tr.TaskItemId into trj
from x in trj.DefaultIfEmpty()
where x.UserId == userId
select t;

But this isn't filtering for a particular UserId, and instead returns 但这不是针对特定的UserId进行过滤,而是返回

Description  IsCompleted   userId  Notes
Task A       0             2       Great
Task B       1             2       Okay
Task C       1             3       Nope
Task D       1             1       I've done this now.
Task E       0             5       Ok. 

See that. 看到那个。 May be you need ome minor changes. 可能您需要一些小的更改。

var query = from t in DbContext.TaskList
    join ti in DbContext.TaskItem on t.TaskListId equals ti.TaskListId
    join tr in DbContext.TaskItemResponse on ti.TaskItemId equals tr.TaskItemId
    where(tr.UserId == '1')
    select new tempObjList
    {
        Description = taskItems.Description,
        IsCompleted = taskItemResponses.IsCompleted,
        userId = TaskItemResponses.userId,
        Notes = TaskItemResponses.Notes
    };

make "tempObjList" model class. 制作“ tempObjList”模型类。

The correct way to convert SQL LEFT JOIN with right side filter to LINQ is to apply the right side filter before the join operator. 转换SQL的正确方法LEFT JOIN与右侧的过滤器,以LINQ是之前应用右侧过滤器join运营商。

Here is the LINQ equivalent of your SQL query (of course you can correct the field names/types if needed): 这是您的SQL查询的LINQ等效项(当然,您可以根据需要更正字段名称/类型):

var query = 
    from t in DbContext.TaskList
    join ti in DbContext.TaskItem on t.TaskListId equals ti.TaskListId
    into tij from ti in tij.DefaultIfEmpty() // left join
    join tr in DbContext.TaskItemResponse.Where(x => x.UserId == userId) // filter
        on ti.TaskItemId equals tr.TaskItemId
    into trj from tr in trj.DefaultIfEmpty() // left join
    select new
    {
        ti.Description,
        IsCompleted = (bool?)tr.IsCompleted,
        userId = (int?)tr.userId,
        tr.Notes 
    };

在您的EF代码中,第一个联接是INNER联接,第二个联接是LEFT OUTER联接

Have a look at these: 看看这些:

Hope these could save you some time. 希望这些可以节省您一些时间。

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

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