我如何将该脚本转换为lambda或linq?
select a.PayoutID,b.PayoutName
from [dbo].[PayoutsOfUser] a
inner join [dbo].[Payout] b on a.PayoutID = b.PayoutID
inner join [dbo].[Users] c on a.UserID = c.UserID
where c.UserID = 16
答案 0 :(得分:0)
var result= PayoutsOfUser.Join(Payout,
a=>a.PayoutID,
b=>b.PayoutID,
(a,b)=>new{PayoutsOfUser=a,Payout=b})
.Join(Users,
a=>a.PayoutsOfUser.UserID,
c=>c.UserID,
(a,c)=>new{a.PayoutsOfUser,a.Payout,Users=c})
.Where(x=>x.Users.UserID==16)
.Select(x=>new
{
a.PayoutID,
b.PayoutName
}).ToList();
答案 1 :(得分:0)
方法语法(=带lambda表达式的语法)比查询语法具有更多功能。因此,我更喜欢在查询语法之上使用方法语法。
但是有一个例外:当连接三个或更多表时,该方法的语法看起来很可怕,就像Sebu在他的回答中所示。 this answer where the two methods for joining three tables are compared
中也显示 pst_n=fiona.open(r'C:\Users\user\Desktop\new\PST')#new pst
pst_o=fiona.open(r'C:\Users\user\Desktop\old\PST')#old_pst
pst_n.schema
d1 = pst_n.schema['properties']
d2 = pst_o.schema['properties']
d1_items = set(d1.items())
d2_items = set(d2.items())
result = sorted([(k, 'd1', v) for k, v in d1_items if (k, v) not in d2_items] +
[(k, 'd2', v) for k, v in d2_items if (k, v) not in d1_items])
result = [(k, v, d) for k, d, v in result]
pprint(result)
的内部表达式是相同的,无论您使用的是方法语法还是查询语法,因此生成的SQL语句差别不会很大。
因此,我的建议是:尽可能使用方法语法,但是为了提高可读性,减少错误,提高可维护性:使用查询语法连接三个表。
如果必须经常进行三个表的联接,请考虑创建一个扩展函数来隐藏联接的完成方式:
请参阅:extension functions demystified
以下函数采用三个输入序列:IQueryable,IQueryable和IQueryable。
它在使用T1Join1Selector和T2Join1Selector提取的键上连接前两个序列,
如果将使用T2Join2Selector和T3Join2Selector进行运算的键上的后两个序列结合在一起
从每个匹配的T1 / T2 / T3,它根据resultSelector创建一个结果
[('ADDRESS', 'int:4', 'd1'),
('ADDRESS', 'str:254', 'd2'),
('AREA', 'float:19.11', 'd2'),
('DEC_ID', 'int:4', 'd1'),
('DEC_ID', 'str:254', 'd2'),
('DESC_', 'str:254', 'd1'),
('FID_PERIVL', 'int:9', 'd1'),
('KAEK', 'str:50', 'd1'),
('KAEK', 'str:12', 'd2'),
('LEN', 'float:19.11', 'd2'),
或者使用查询语法连接三个表:
IQueryable
用法类似于使用方法语法联接两个表的方式:
public static IQueryable<TResult> Join<T1, T2, T3,
TKeyJoin1, TKeyJoin2, TResult>(
this IQueryable<T1> table1,
IQueryable<T2> table2,
IQueryable<T3> table3,
Expression<Func<T1, TKeyJoin1>> table1Join1KeySelector,
Expression<Func<T2, TKeyJoin1>> table2Join1KeySelector,
Expression<Func<T2, TKeyJoin2>> table2Join2KeySelector,
Expression<Func<T3, TKeyJoin2>> table3Join2KeySelector,
Expression<Func<T1, T2, T3, Tresult>> resultSelector)
{
return Tabl1.Join(table2, // join table1 and table2
t1 => table1Join1KeySelector(t1), // select the key from table1 for the first join
t2 => table2Join1KeySelector(t2), // select the key from table2 for the first join
(t1, t2) => new // remember the matching records as T1 and T2
{
T1 = t1,
T2 = t2,
})
// use this as input for the second join:
.Join(table3,
// use the T2 in the result of the first join as key for the second join
joinedT1andT2 => table2Join2KeySelector(joinedT1andT2.T2),
t3 => table3Join2KeySelector(t3), // select the key from table3 for the 2nd join
// and use the result of the first and second join to create a linq-result:
(joinedT1andT2, t3) => resultSelector(joinedT1andT2.T1, joinedT1andT2.T2, T3);
}
我看到您的第二个联接位于a和c上,而我的第二个联接位于b和c上。我确定您会知道如何根据需要重写代码
由于此函数的结果是一个IQueryable,因此该函数将仅更改表达式。查询尚未执行。因此,您可以安全地将其与其他IQueryable函数混合使用:
public static IQueryable<TResult> Join<T1, T2, T3,
TKeyJoin1, TKeyJoin2, TResult>(
this IQueryable<T1> table1,
IQueryable<T2> table2,
IQueryable<T3> table3,
Expression<Func<T1, TKeyJoin1>> table1Join1KeySelector,
Expression<Func<T2, TKeyJoin1>> table2Join1KeySelector,
Expression<Func<T2, TKeyJoin2>> table2Join2KeySelector,
Expression<Func<T3, TKeyJoin2>> table3Join2KeySelector,
Expression<Func<T1, T2, T3, Tresult>> resultSelector)
{
return select resultSelector(table1, table2, table3)
from table1
join table2 on table1Join1KeySelector(table1) == table2Join1KeySelector(table2)
join table3 on table2Join2KeySelector(table2) == table3Join2KeySelector(table3)
}
在执行不返回var result = a.Join(b, c, // join your tables a, b, c
t1 => t1.PayoutId, // first join on a.PayoutID = b.PayoutID
t2 => t2.PayoutId,
t2 => t2.UserId, // second join on b.UserID = c.UserID
t3 => t3.UserId,
(t1, t2, t3) => new // from the matching records create one new object
{
PayoutId = t1.PayoutId,
PayoutName = t2.PayoutName,
...
});
的操作之前,查询仍不会执行,例如var resultQuery = a.Where(t1 => t1.Name = ...)
.Join( /* 3-table join as described above */ )
.GroupBy(joinResult => ...)
.Take(4);
/ IQueryable
/ ToList
/ ...