203

我在 LINQ to SQL 示例中看到了很多关于如何在查询语法中进行连接的示例,但我想知道如何使用方法语法来做到这一点?例如,我该如何执行以下操作

var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             select new { SomeClass = sc, SomeOtherClass = soc }

有一个.Join()?谁能说明或提供另一个简单的例子?

4

3 回答 3

302
var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             select new { SomeClass = sc, SomeOtherClass = soc };

相当于:

var result = enumerableOfSomeClass
    .Join(enumerableOfSomeOtherClass,
          sc => sc.Property1,
          soc => soc.Property2,
          (sc, soc) => new
                       {
                           SomeClass = sc,
                           SomeOtherClass = soc
                       });

如您所见,当涉及到连接时,查询语法通常比 lambda 语法更具可读性。

于 2010-07-10T03:20:29.557 回答
133

贾斯汀正确地展示了连接后跟一个select. 如果您还有其他东西,由于透明标识符(C# 编译器用来传播连接的两半范围的机制),它会变得更加棘手。

所以稍微改变贾斯汀的例子:

var result = from sc in enumerableOfSomeClass
             join soc in enumerableOfSomeOtherClass
             on sc.Property1 equals soc.Property2
             where sc.X + sc.Y == 10
             select new { SomeClass = sc, SomeOtherClass = soc }

将被转换成这样的东西:

var result = enumerableOfSomeClass
    .Join(enumerableOfSomeOtherClass,
          sc => sc.Property1,
          soc => soc.Property2,
          (sc, soc) => new { sc, soc })
    .Where(z => z.sc.X + z.sc.Y == 10)
    .Select(z => new { SomeClass = z.sc, SomeOtherClass = z.soc });

这里z是透明标识符 - 但由于它是透明的,您在原始查询中看不到它:)

于 2010-07-10T06:10:19.107 回答
5

要在此处添加其他答案,如果您想使用 where 子句创建第三种不同类型的新对象(例如,不是您的实体框架对象的对象),您可以这样做:

public IEnumerable<ThirdNonEntityClass> demoMethod(IEnumerable<int> property1Values)
{
    using(var entityFrameworkObjectContext = new EntityFrameworkObjectContext )
    {
        var result = entityFrameworkObjectContext.SomeClass
            .Join(entityFrameworkObjectContext.SomeOtherClass,
                sc => sc.property1,
                soc => soc.property2,
                (sc, soc) => new {sc, soc})
            .Where(s => propertyValues.Any(pvals => pvals == es.sc.property1)
            .Select(s => new ThirdNonEntityClass 
            {
                dataValue1 = s.sc.dataValueA,
                dataValue2 = s.soc.dataValueB
            })
            .ToList();
    }

    return result;

}    

请特别注意在 Where 和 Select 子句中创建的中间对象。

请注意,这里我们还查找任何具有与输入列表中的一个匹配的 property1 的连接对象。

我知道这比最初的提问者所寻找的要复杂一些,但希望它会对某人有所帮助。

于 2015-05-05T16:14:25.247 回答