帮助理解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 =第二个表的对象类型

  1. db.TableB.Where( b => b.MyField == someValue )这是第二个表的元素类型
  2. o => o.someFieldID第一个表的键
  3. i => i.someFieldID第二个表的键(与第一个表中的键匹配)
  4. (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