帮助理解Enumerable.Join方法
昨天我发布了关于在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)等的签名要求。
Eric和Nick都提供了很好的答案。
您还可以使用查询语法编写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表达式的信息。 它们允许以更简单和更优雅的方式表达非常强大的想法。 这是一个很深刻的话题,但基本知识很容易理解。 它是一个函数,您可以像变量一样传递,或作为参数传递给其他函数。
连接语法是
FirstTable.Join(SecondTable, FirstTableKeyExtractor, SecondTableKeyExtractor, Selector)
所以你有两张桌子。 您有两个表共有的密钥。 您提供了两个关键提取器,它们知道如何从表中的每一行获取密钥。
连接逻辑标识具有相同密钥的每对表中的一对行。
然后,每个行都通过选择器运行以投影结果。
这是否回答你的问题?
加入的说明。
b
=第一个表的对象类型o
=第一个表的对象类型i
=第二个表的对象类型
-
db.TableB.Where( b => b.MyField == someValue )
这是第二个表的元素类型 -
o => o.someFieldID
第一个表的键 -
i => i.someFieldID
第二个表的键(与第一个表中的键匹配) -
(o,i) => o
要返回的对象,在本例中是第一个表的对象类型。
此查询表示将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