2010-05-24 51 views
2
var folders = from r in this.bdd.Rights 
       join f in this.bdd.Folders on r.RightFolderId equals f.FolderId 
       join rs in this.bdd.RightSpecs on r.RightSpecId equals rs.SpecIdRight 
       where r.RightUserId == userId 
       where rs.SpecRead == true 
       where rs.SpecWrite == true 
       select f; 

如何在其他语法中转换此linq查询?switch linq语法

var folders = this.bdd.Rights.Where(r => r..... 
+0

请提供有关“其他语法”的含义的更多信息。 – 2010-05-24 15:51:52

+0

对不起,我的英语太糟糕了! 第一个代码看起来像一个“SQL查询”。但是我想要与LINQPad的链接使用Lambda语法 – scrat789 2010-05-24 16:28:21

回答

7

老实说,当谈到使用连接时,我坚持使用Query语法。

该查询的Lambda语法将接近不可读。

不幸的是,我现在没有时间输入转换,所以我会建议你下载LINQPad。它将允许您采用查询语法并查看Lambda翻译以及生成的SQL。

Download LINQPad

所以......我决定采取刺伤实践的代码。我认为它看起来是这样的:

var folders = this.bdd.Rights 
        .Join(this.bdd.Folders, 
         r => r.RightFolderId, 
         f => f.FolderId, 
         (r,f) => new { Outer = r, Inner = f }) 
        .Join(this.bdd.RightSpecs, 
         r => r.Outer.RightSpecId, 
         rs => rs.SpecIdRight, 
         (r,rs) => new { Outer = r, Inner = rs }) 
        .Where(r => r.Outer.Outer.RightUserId == userId) 
        .Where(r => r.Inner.SpecRead == true) 
        .Where(r => r.Inner.SpecWrite == true) 
        .Select(r => r.Outer.Inner); 

就像我说的,这是实践,所以我不是100%肯定,如果这是正确的它绝对应该给你一个想法,为什么你可能要考虑保持查询语法。

+2

+ 1(如果可以的话)的相同结果,我保留下载它的意思,现在我知道我必须! – 2010-05-24 16:00:02

+0

我对你很好,该查询的Lambda语法不可读! 感谢您使用lambda语法的示例,我想我会保留此查询的SQL语法! – scrat789 2010-05-24 16:17:10

+0

您的Lambda语法示例适用! – scrat789 2010-05-24 16:25:23

0

如果您在LinqToSql设计器中添加这些项目的关联,您将获得导航属性。这些属性使编写查询变得更容易,而不用担心加入的概念。

我会重写原始查询以消除连接的重复。您需要过滤文件夹查询,因此请编写一个查询来过滤文件夹。

var folderQuery = 
    from f in this.bdd.Folders 
    where f.Rights.Any(r => r.RightUserId = userId && 
    r.RightSpecs.Any(rs => rs.SpecRead && rs.SpecWrite)) 
    select f; 

然后它翻译成这样的:在C#4规格

var folderQuery = this.bdd.Folders 
    .Where(f => f.Rights.Any(r => r.RightUserId = userId && 
    r.RightSpecs.Any(rs => rs.SpecRead && rs.SpecWrite)); 
+0

我不能做“.Where(f => f.Rights”, Rights不是我文件夹的属性,它是另一张表 – scrat789 2010-05-24 16:21:47

+0

打开LinqToSql设计器。在文件夹和权限之间添加一个关联。 – 2010-05-24 16:32:13

9

阅读部分7.16.2。所有规则都在那里。

让我们来看看它。您有:

from r in this.bdd.Rights 
join f in this.bdd.Folders on r.RightFolderId equals f.FolderId 
join rs in this.bdd.RightSpecs on r.RightSpecId equals rs.SpecIdRight 
where r.RightUserId == userId 
where rs.SpecRead == true 
where rs.SpecWrite == true 
select f; 

细则中指出

与连接子句的查询表达式没有到后面跟着一个非SELECT子句

from x1 in e1 
join x2 in e2 on k1 equals k2 
... 

以外的东西翻译分成

from * in (e1) 
. Join(e2 , x1 => k1 , x2 => k2 , (x1 , x2) => new { x1 , x2 }) 
... 

好了,我们开始通过翻译查询到

from * in 
(this.bdd.Rights) 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (*, f)=> new {r, f}) 
join rs in this.bdd.RightSpecs on r.RightSpecId equals rs.SpecIdRight 
where r.RightUserId == userId 
where rs.SpecRead == true 
where rs.SpecWrite == true 
select f; 

现在同样的规则再次适用;我们有一个查询表达式,其中有一个没有into的连接子句,后面跟着一个select以外的东西。如此变成:

from ** in 
((this.bdd.Rights) 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (r, f)=> new {r, f})) 
.Join(
    this.bdd.RightSpecs, 
    *=>r.RightSpecId, 
    rs=>rs.SpecIdRight, 
    (*, rs)=> new {*, rs}) 
where r.RightUserId == userId 
where rs.SpecRead == true 
where rs.SpecWrite == true 
select f; 

接下来的规则是什么?咨询规格:用

查询表达式where子句

from x in e 
where f 
... 

被翻译成

from x in (e) . Where (x => f) 
... 

OK,让我们应用这一转变三次,获得

from ** in 
(((((this.bdd.Rights) 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (r, f)=> new {r, f})) 
.Join(
    this.bdd.RightSpecs, 
    *=>r.RightSpecId, 
    rs=>rs.SpecIdRight, 
    (*, rs)=> new {*, rs})) 
.Where(**=>r.RightUserId == userId)) 
.Where(**=>rs.SpecRead == true)) 
.Where(**=>rs.SpecWrite == true) 
select f; 

现在呢?咨询规格:

from x in e select v 

被翻译成

(e) . Select (x => v) 

所以上面的代码被转换为

((((((this.bdd.Rights) 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (r, f)=> new {r, f})) 
.Join(
    this.bdd.RightSpecs, 
    *=>r.RightSpecId, 
    rs=>rs.SpecIdRight, 
    (*, rs)=> new {*, rs})) 
.Where(**=>r.RightUserId == userId)) 
.Where(**=>rs.SpecRead == true)) 
.Where(**=>rs.SpecWrite == true)) 
.Select(**=>f); 

其中***是透明的标识符。因此,这是再进一步转化为

((((((this.bdd.Rights) 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (r, f)=> new {r, f})) 
.Join(
    this.bdd.RightSpecs, 
    t1=>t1.r.RightSpecId, 
    rs=>rs.SpecIdRight, 
    (t1, rs)=> new {t1, rs})) 
.Where(t2=>t2.t1.r.RightUserId == userId)) 
.Where(t2=>t2.rs.SpecRead == true)) 
.Where(t2=>t2.rs.SpecWrite == true)) 
.Select(t2=>t2.t1.f); 

我们介绍了一大堆不必要的括号在那里。我们可以把它们拿出来说,这相当于

this.bdd.Rights 
.Join(
    this.bdd.Folders, 
    r=>r.RightFolderId, 
    f=>f.FolderId, 
    (r, f)=> new {r, f}) 
.Join(
    this.bdd.RightSpecs, 
    t1=>t1.r.RightSpecId, 
    rs=>rs.SpecIdRight, 
    (t1, rs)=> new {t1, rs}) 
.Where(t2=>t2.t1.r.RightUserId == userId) 
.Where(t2=>t2.rs.SpecRead == true) 
.Where(t2=>t2.rs.SpecWrite == true) 
.Select(t2=>t2.t1.f); 

很容易。这只是一个简单的句法重写,除了对透明标识符进行一些分析之外。