Entity Framework使用Join方法和Lambda进行连接

53

看起来使用 LINQ 进行连接有不同的方法。其中一种更为直接,只涉及像这样联接表:

var found = from c in s.categories
            join cm in s.categorymaps on c.CategoryId equals cm.ChildCategoryId
            select c;

使用lambda表达式也有另一种方法,我正在努力尝试弄清楚如何使用这种语法进行连接。是否可以提供详细说明和大量示例的链接?或者只是简单地使用示例演示如何使用这种令人困惑的语法?

var x = _session.All<category>().Join<categorymap,category, ....
3个回答

147

通常情况下我更喜欢使用带有 LINQ 的 lambda 语法,但在 Join 这个方法中我更偏向于使用查询语法,纯粹是为了可读性。

尽管如此,以下是与您上面查询等效的代码(我觉得未经测试):

var query = db.Categories         // source
   .Join(db.CategoryMaps,         // target
      c => c.CategoryId,          // FK
      cm => cm.ChildCategoryId,   // PK
      (c, cm) => new { Category = c, CategoryMaps = cm }) // project result
   .Select(x => x.Category);  // select result

根据你想要返回的内容,可能需要调整投影方式,但这就是要点。


到目前为止,这是我找到的最好的解释,我能够解决我的连接问题,谢谢。 - Manny
4
谁在微软坐着决定这个语法是合理的?我想见他并问他一两个问题。 - DanteTheSmith
这样的代码有一个缺点,就是从Join中获得的匿名类很难传递给其他组件,例如View、Controller或事件框架。我喜欢编写明确的中介类,其中包含我在Join中关心的属性混合。结果是我获得了强类型和更好的SQL性能,因为返回的列列表比完整行更受限制。 - Chris Moschini

13

你可以在这里找到一些示例

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable contacts = ds.Tables["Contact"];
DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    contacts.AsEnumerable().Join(orders.AsEnumerable(),
    order => order.Field<Int32>("ContactID"),
    contact => contact.Field<Int32>("ContactID"),
    (contact, order) => new
    {
        ContactID = contact.Field<Int32>("ContactID"),
        SalesOrderID = order.Field<Int32>("SalesOrderID"),
        FirstName = contact.Field<string>("FirstName"),
        Lastname = contact.Field<string>("Lastname"),
        TotalDue = order.Field<decimal>("TotalDue")
    });


foreach (var contact_order in query)
{
    Console.WriteLine("ContactID: {0} "
                    + "SalesOrderID: {1} "
                    + "FirstName: {2} "
                    + "Lastname: {3} "
                    + "TotalDue: {4}",
        contact_order.ContactID,
        contact_order.SalesOrderID,
        contact_order.FirstName,
        contact_order.Lastname,
        contact_order.TotalDue);
}
或者只需在 Google 上搜索“linq join method syntax”。

谢谢大家的帮助。我找到了这个非常有用的链接,它真正解释了相当复杂的join()方法,所以我想分享给其他人学习。 - Mason

1
如果您已配置了1-n导航属性,我建议您使用以下方法:
var query = db.Categories                                  // source
   .SelectMany(c=>c.CategoryMaps,                          // join
      (c, cm) => new { Category = c, CategoryMaps = cm })  // project result
   .Select(x => x.Category);                               // select result

使用多重嵌套连接更加清晰易懂,且外观更佳。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接