如何从复杂的SQL创建LINQ?

时间:2018-07-04 13:59:48

标签: c# sql linq

我有这个SQL查询:

time_zone

我正在尝试将此查询转换为LINQ。到目前为止,这是我所做的:

std::thread{on_utc_offset_change<decltype(lambda)>,
            date::locate_zone("America/New_York"),
            lambda}.detach();

此行出现错误:

 SELECT D.ID
 FROM Documents AS D
 INNER JOIN DocClasses AS DC WITH (NOLOCK) 
 ON D.DocClass = DC.ID
 INNER JOIN DocSubClasses AS DSC WITH (NOLOCK) 
 ON D.DocSubClass = DSC.ID AND DSC.DocClassID = DC.ID
 INNER JOIN DocPathFolders AS F WITH (NOLOCK) 
 ON D.DocPathFolderID = F.ID
 WHERE 
    DC.ShortName = 'PAY' AND DSC.Name = 'xxxxx' 
    AND UPPER(F.Description) = 'READY TO SEND'

在这里,我遇到以下错误:

  

名称“ DSC”不在“ equals”左侧的范围内

     

名称'DC'不在'equals'右侧的范围内

我是LINQ的新手,这就是为什么我无法解决这些错误的原因。我希望就以上提出任何建议。谢谢。

5 个答案:

答案 0 :(得分:1)

您应该像这样重新排列匿名对象中的属性:

join DSC in ctx.DocSubClasses 
on new { D.DocSubClass, DC.ID } equals new { DSC.DocClassID, DSC.ID }

右边的应该是您要加入的表(DSC),左边的应该是以前的表

答案 1 :(得分:0)

这是我解决问题的方法:

from D in ctx.Documents
join DC in ctx.DocClasses on D.DocClass equals DC.ID
join DSC in ctx.DocSubClasses on new { D.DocSubClass, DC.ID } equals new { DocSubClass = DSC.ID, ID = DSC.DocClassID }
join F in ctx.DocPathFolders on D.DocPathFolderID equals F.ID
where DC.ShortName == "PAY" && DSC.Name == "xxxx" && (F.Description).ToUpper() == "READY TO SEND"
select D.ID;

答案 2 :(得分:0)

只需将DSC切换到等号的右侧,将DC切换到左侧,就可以正常工作。

item is not unique_sentinel_singleton

答案 3 :(得分:0)

提示:假设您已经在数据库中适当地设置了关系,则几乎不需要使用“ join”。用LINQ编写起来更容易,并且关系被公开为“导航属性”。您只需使用“点符号”。即:

var result = from d in ctx.Documents
           where d.DocClasses.Any( dc => dc.ShortName == "PAY" 
              && dc.DocSubClasses.Any( dsc => dsc.Name == "xxxxx" )
              && d.DocPathFolders.Any( dpf => dpf.Description.ToUpper() == "READY TO SEND" )
            select d.ID;

注意:我们对您的模型不了解。我认为这种关系是一对多的。如果是多对一,则只需使用以下符号:

where d.DocClass.ShortName == "PAY" 
                  && d.DocClass.DocSubClass.Name == "xxxxx" 
                  && d.DocPathFolder.Description.ToUpper() == "READY TO SEND" 

HINT2:从LinqPad.net下载并开始使用Linqpad。这是一个很棒的工具,您不仅可以测试LINQ查询,还可以用作.Net暂存器。

答案 4 :(得分:0)

您可以尝试使用Lambda Join来代替LINQ

您的JOIN语句类似于下面的Lambda

C#Fiddle

var result = ctx.Documents.Join(ctx.DocClasses , d => new { Id = d.DocClass }, dc => new { Id = dc.ID }, (d, dc) => new { doc = d, docClass = dc }) //INNER JOIN DocClasses  
                          .Join(ctx.DocSubClasses , d => new { sc = d.doc.DocSubClass, Id = d.docClass.ID }, dsc => new { sc = dsc.ID, Id = dsc.DocClassID }, (d, dsc) => new { doc = d, dsc = dsc } ) //INNER JOIN DocSubClasses
                          .Join(ctx.DocPathFolders, d => new { fId = d.doc.doc.DocPathFolderID }, f => new { fId = f.ID }, (d, f) => new { doc = d, f = f }) //INNER JOIN DocPathFolders
                          .Where(x => x.doc.doc.docClass.ShortName == "PAY" && x.doc.dsc.Name == "xxxxx" && x.f.Description.ToUpper() == "READY TO SEND")//Apply where clause
                          .Select(y => y.doc.doc.doc.ID);//Select whatever you want