gpt4 book ai didi

c# - 切换 linq 语法

转载 作者:行者123 更新时间:2023-11-30 18:55:43 24 4
gpt4 key购买 nike

 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 查询转换为其他语法?

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

最佳答案

阅读 C# 4 规范中的第 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;

规范说

A query expression with a join clause without an into followed by something other than a select clause

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

is translated into

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;

下一个适用的规则是什么?查阅规范:

A query expression with a where clause

from x in e
where f
...

is translated into

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

好的,所以我们应用该转换三次并得到

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

is translated into

( 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);

简单易行。这只是一个简单的语法重写,除了对透明标识符的一些分析。

关于c# - 切换 linq 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2898199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com