简体   繁体   English

如何从复杂的SQL创建LINQ?

[英]How to create LINQ from complex SQL?

I've this SQL query: 我有这个SQL查询:

 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'

I'm trying to convert this query into LINQ. 我正在尝试将此查询转换为LINQ。 Here is what I've done so far: 这是我到目前为止所做的:

 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, DSC.DocClassID } equals new { DSC.ID, DC.ID }
 join F in ctx.DocPathFolders 
     on D.DocPathFolderID equals F.ID
 where 
     DC.ShortName == "PAY" 
     && DSC.Name == "xxxxx" 
     && (F.Description).ToUpper() == "READY TO SEND"
 select D.ID;

I'm getting error in this line: 我在这行中遇到错误:

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

Here, I'm getting following error: 在这里,我收到以下错误:

The name 'DSC' is not in scope on the left side of 'equals' 名称'DSC'不在'equals'左侧的范围内

The name 'DC' is not in scope on the right side of 'equals' 名称'DC'不在'equals'右侧的范围内

I'm new in LINQ and that's why I can't solve these error. 我是LINQ的新手,这也是我无法解决这些错误的原因。 I would apperciate any suggestion on the above. 我会对上述内容提出任何建议。 Thanks. 谢谢。

You should rearrange the properties in the anonymous objects like this: 您应该重新排列匿名对象中的属性,如下所示:

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

Those on the right should be of the table you are joining ( DSC ) and those on the left can be of previous tables 右边的那些应该是你加入的表格( DSC ),而左边的那些可以是前面的表格

Here is how I've solved my issue: 以下是我解决问题的方法:

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;

只需将DSC切换到等于右侧,将DC切换到左侧,它应该可以正常工作。

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

Hint: Provided you have set your relations appropriately in your database you almost never need to use "join". 提示:如果您在数据库中正确设置了关系,则几乎不需要使用“加入”。 It is easier to write in LINQ and relations are exposed as "navigational properties". 在LINQ中编写更容易,关系暴露为“导航属性”。 You simply use "dot notation". 你只需使用“点符号”。 ie: 即:

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;

Note: We don't have any idea on your model. 注意:我们对您的型号一无所知。 I assumed the relations as 1-To-Many. 我认为这种关系是1-To-Many。 If it were Many-To-1 then you would simply use notation like: 如果它是多对一,那么你只需使用如下符号:

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

HINT2: Download and start using Linqpad from LinqPad.net. HINT2:从LinqPad.net下载并开始使用Linqpad。 It is a great tool where you can not only test your LINQ queries but use as a .Net scratch pad. 它是一个很棒的工具,您不仅可以测试LINQ查询,还可以用作.Net便笺簿。

You can try with Lambda Join instead of using LINQ . 您可以尝试使用Lambda Join而不是使用LINQ

Your JOIN statements look like below in Lambda . 您的JOIN语句在Lambda如下所示。

C# Fiddle C# 小提琴

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

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

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