2010-05-24 50 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); 

很容易。這只是一個簡單的句法重寫,除了對透明標識符進行一些分析之外。