昨天我posted this question关于在Join()方法中使用lambdas来检查2个实体中是否存在2个条件。我收到了关于这个问题的答案,这个问题非常有效。我在阅读了关于Enumerable.Join()方法的MSDN文章之后想到了,我完全理解发生了什么,但我没有。有人可以帮我理解下面代码中的内容(具体是Join()方法)吗?提前谢谢。
if (db.TableA.Where( a => a.UserID == currentUser )
.Join( db.TableB.Where( b => b.MyField == someValue ),
o => o.someFieldID,
i => i.someFieldID,
(o,i) => o )
.Any())
{
//...
}
编辑: 具体来说,我很好奇最后3个参数,以及实际发生了什么。它们如何导致Func(TOuter,TKey),Func(TInner,TKey)等的签名要求。
答案 0 :(得分:19)
连接语法是
FirstTable.Join(SecondTable, FirstTableKeyExtractor, SecondTableKeyExtractor, Selector)
所以你有两张桌子。您有两个表共有的密钥。您提供了两个关键提取器,它们知道如何从表中的每一行获取密钥。
连接逻辑标识每对表中具有相同密钥的行对。
然后,每个行都通过选择器运行以生成结果。
这会回答你的问题吗?
答案 1 :(得分:5)
加入的说明。
b
=第一个表的对象类型
o
=第一个表的对象类型
i
=第二个表的对象类型
db.TableB.Where( b => b.MyField == someValue )
这是第二个表的元素类型o => o.someFieldID
第一张表的关键i => i.someFieldID
第二个表的键(与第一个表中的键匹配)(o,i) => o
要返回的对象,在本例中是第一个表的对象类型。答案 2 :(得分:3)
您也可以使用查询语法编写Linq查询表达式(与您在示例中使用的方法语法相对):
var query = from a in db.TableA
join b in db.TableB on a.someFieldID equals b.someFieldID
where a.UserID == currentUser && b.MyField == someValue
select a;
if (query.Any()) {
...
}
更新
你似乎被困在lambda表达式上。这是一个像变量一样传递的函数。 lambda表达式等同于匿名委托(或匿名方法,对我来说更通用)。
以下是使用lambda表达式作为委托的查询(当然,将EntityType替换为从TableA返回的实体的类型):
if (db.TableA.Where( delegate(EntityType a) { return a.UserID == currentUser; } )
.Join( db.TableB.Where( delegate(EntityType b) { return b.MyField == someValue; } ),
delegate(EntityType o) { return o.somefieldId); },
delegate(EntityType i) { return i.someFieldId); },
delegate(EntityType o, EntityType i) { return o; })
.Any())
{ // ... }
注意:lambda表达式具有重要的方面,使其不仅仅是匿名方法的等价物。我建议您查看其他SO问题,并在线阅读有关lambda表达式的信息。它们允许以更简单和优雅的方式表达非常强大的想法。这是一个很深刻的话题,但基本知识很容易理解。这是一个函数,您可以像变量一样传递,或作为其他函数的参数传递。
答案 3 :(得分:2)
此查询表示加入TableA
到TableB
TableA.someFieldID == TableB.someFieldID
,然后从TableA中选择结果并查看是否有任何结果
就SQL而言,就像这样,即使它不是Linq-to-SQL ......如果你熟悉SQL,这可能更有意义:
Select Count(*)
From TableA a
Join TableB b
On a.someFieldID = b.someFieldID
然后检查Count(*)
是否> 0