帮助理解Enumerable.Join方法

时间:2010-03-13 19:03:36

标签: c# .net asp.net linq

昨天我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)等的签名要求。

4 个答案:

答案 0 :(得分:19)

连接语法是

FirstTable.Join(SecondTable, FirstTableKeyExtractor, SecondTableKeyExtractor, Selector)

所以你有两张桌子。您有两个表共有的密钥。您提供了两个关键提取器,它们知道如何从表中的每一行获取密钥。

连接逻辑标识每对表中具有相同密钥的行对。

然后,每个行都通过选择器运行以生成结果。

这会回答你的问题吗?

答案 1 :(得分:5)

加入的说明。

b =第一个表的对象类型 o =第一个表的对象类型 i =第二个表的对象类型

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

此查询表示加入TableATableB 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