【问题标题】:How can I convert this SQL query to Linq with C#如何使用 C# 将此 SQL 查询转换为 Linq
【发布时间】:2017-11-29 14:23:34
【问题描述】:

由于我是 Linq 的新手,因此无法将此 SQL 查询转换为 Linq,因此我粘贴了我已经尝试过的代码,它给出了空记录。

提前致谢。

这是我尝试过的 Linq C# 语句:

from ts in Db.Tasks

join prt in Db.ProjectTasks on ts.Id equals prt.TaskId into PojTsk
from t1 in PojTsk 

join TL in Db.Timeline on ts.Id equals TL.TypeId into Tmln
from t2 in Tmln

join DUR in Db.Duration on ts.Id equals DUR.TypeId into Dur
from t3 in Tmln

where t1.ProjectId == ProjectId 
&& t2.Type == (int)Provider.EntityType.TASK 
&& t3.Type == (int)Provider.EntityType.TASK
select ts

这是我尝试使用 C# 转换为 Linq 的 SQL 查询:

SELECT 
    CONCAT('T', R1.Id)  as Id, 
    R1.Name, R1.Description, R1.Priority, 
    R1.Stage, R1.Status, R1.CreatorId, 
    R2.ProjectId, R3.StartDate, R3.EndDate, 
    R3.LatestEndDate, R3.LatestStartDate, 
    R3.EarliestStartDate, R3.ActualStart, R3.ActualEnd, 
    R3.RemTime, R3.ReshowDate, R3.RemTime, R3.Completed, 
    R4.ActualDuration, R4.ActualDurationPlanned      
FROM 
    (SELECT * 
     FROM [ProjectManagement].[dbo].[Tasks] AS TS) AS R1
JOIN
    (SELECT * 
     FROM [ProjectManagement].[dbo].[ProjectTasks]) AS R2 ON R1.Id = R2.TaskId
LEFT JOIN
    (SELECT * FROM [ProjectManagement].[dbo].[Timelines] 
     WHERE Type = 3) AS R3 ON R1.Id = R3.TypeId
LEFT JOIN
    (SELECT * FROM [ProjectManagement].[dbo].[Durations] 
     WHERE Type = 3) AS R4 ON R1.Id = R4.TypeId
WHERE
    ProjectId = 1

My sql query result in SQL Server Management Studio

【问题讨论】:

  • 没有select * from的语法。
  • 你试过这个吗? sqltolinq.com
  • @Mahesh Malpani,你怎么能说“没有 select * from 的语法”我已经在我的 SQL Server Management Studio 上测试了这个查询
  • 您现在询问特定库。不确定,但您可以使用实体框架和 .net linq 来代替

标签: c# sql linq


【解决方案1】:

即使仍然无法确定应该先执行哪个查询,我已经弄清楚了查询执行步骤:

(1) ProjectId = 1 的 ProjectTasks 表的内连接 Tasks 表,

(2) 左连接 (1) 到 Timelines 表,其中 Type = 3,

(3) 左连接 (2) 到类型 = 3 的持续时间表。

我最接近使用 LINQ 的 SQL 查询的方法(我既没有测试过 LINQPad,也没有直接测试过 VS):

// first inner join
var query = (from R1 in Tasks
join R2 in ProjectTasks on R1.Id equals R2.TaskId into Group1

// second left join
from T1 in Group1.DefaultIfEmpty() 
join R3 in (from t in Timelines where t.Type == 3 select t) on T1.Id equals R3.TypeId into Group2

// third left join
from T2 in Group2.DefaultIfEmpty()
join R4 in (from d in Durations where d.Type == 3 select d) on T2.Id equals R4.TypeId

// still not sure to determine where condition here...
where T2.ProjectId == 1 // join result condition

select new {
    Id = T1.Id.ToString().Concat("T"), // assume Tasks.Id is an int identity column converted to String value
    Name = T1.Name,
    Description = T1.Description,
    Priority = T1.Priority,
    Stage = T1.Stage,
    Status = T1.Status,
    CreatorId = T1.CreatorId,
    ProjectId = T1.ProjectId,
    StartDate = T2.StartDate,
    EndDate = T2.EndDate,
    LatestEndDate = T2.LatestEndDate,
    EarliestStartDate = T2.EarliestStartDate,
    ActualStart = T2.ActualStart,
    ActualEnd = T2.ActualEnd,
    RemTime = T2.RemTime,
    ReshowDate = T2.ReshowDate,
    Completed = T2.Completed,
    ActualDuration = R4.ActualDuration,
    ActualDurationPlanned = R4.ActualDurationPlanned
}).ToList();

CMIIW。

【讨论】:

  • 感谢您的重播,但结果仍然为空。
【解决方案2】:

试试这个:

from ts  in Db.Tasks
join prt in Db.ProjectTasks on ts.Id equals prt.TaskId
from tl  in Db.Timeline.Where(x => (x.TypeId == ts.Id)
                                && (x.Type == (int)Provider.EntityType.TASK))
                       .DefaultIfEmpty()
from dur in Db.Duration.Where(x => (x.TypeId == ts.Id)
                                && (x.Type == (int)Provider.EntityType.TASK))
                       .DefaultIfEmpty()

where  (prt.ProjectId == ProjectId)

select new {
    Id = "T" + ts.Id,
    ts.Name,
    ts.Description,
    //...

    prt.ProjectId,

    tl.StartDate,
    tl.EndDate,
    tl.LatestEndDate,
    //...

    dur.ActualDuration,
    dur.ActualDurationPlanned
}

from x in y.DefaultIfEmpty() 是一种创建LEFT JOIN 的简单方法。

编辑:在左连接中更改了.Where()

【讨论】:

  • 结果仍然为空。
  • 我尝试了你的 Linq 并且还更改了 where 条件但没有运气(从 Db.Tasks 中的 ts 加入 ts.Id 上 Db.ProjectTasks 中的 prt 等于 Db.Timeline.Where 中的 tl 中的 prt.TaskId( x => x.TypeId == ts.Id && x.Type == 3) 来自 dur 在 Db.Duration.Where(x => x.TypeId == ts.Id && x.Type == 3) where (prt .ProjectId == ProjectId)
  • 查看此答案以记录 EF 生成的 SQL:stackoverflow.com/a/20751723/1869660 然后更容易看出问题所在。 (注意:我更新了我的答案,你更正了 where 条件)
  • 好的,但是找到 EF 生成的 SQL(请参阅我评论中的链接)。这样就更容易看出问题所在了。
  • pastie.org/10871686 我收到了这个查询。通过登录,你能帮忙吗,我认为这是内连接而不是左连接
猜你喜欢
  • 1970-01-01
  • 2016-01-23
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
相关资源
最近更新 更多