首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在LINQ lambda中实现多个表的连接

如何在LINQ lambda中实现多个表的连接
EN

Stack Overflow用户
提问于 2012-03-15 21:00:06
回答 6查看 233.4K关注 0票数 98

我正尝试在LINQ中的多个表之间执行连接。我有以下几个类:

代码语言:javascript
复制
Product {Id, ProdName, ProdQty}

Category {Id, CatName}

ProductCategory{ProdId, CatId} //association table

我使用以下代码(其中productcategoryproductcategory是上述类的实例):

代码语言:javascript
复制
var query = product.Join(productcategory, p => p.Id, pc => pc.ProdID, (p, pc) => new {product = p, productcategory = pc})
                   .Join(category, ppc => ppc.productcategory.CatId, c => c.Id, (ppc, c) => new { productproductcategory = ppc, category = c});

使用这段代码,我从下面的类中获得了一个对象:

代码语言:javascript
复制
QueryClass { productproductcategory, category}

其中producproductcategory的类型为:

代码语言:javascript
复制
ProductProductCategoryClass {product, productcategory}

我不知道连接的“表”在哪里,我期望的是一个包含相关类的所有属性的单类。

我的目标是用查询得到的一些属性填充另一个对象:

代码语言:javascript
复制
CategorizedProducts catProducts = query.Select(m => new { m.ProdId = ???, m.CatId = ???, //other assignments });

我如何才能实现这个目标?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-03-15 23:18:52

对于连接,我强烈倾向于查询语法,因为所有细节都隐藏得很好(其中最重要的是中间投影所涉及的透明标识符,这些标识符在点语法等效项中很明显)。然而,你问到了Lambdas,我认为你已经拥有了你需要的一切-你只需要把它们放在一起即可。

代码语言:javascript
复制
var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new { ppc, c })
    .Select(m => new { 
        ProdId = m.ppc.p.Id, // or m.ppc.pc.ProdId
        CatId = m.c.CatId
        // other assignments
    });

如果需要,您可以将连接保存到局部变量中并在以后重用它,尽管缺少其他相反的细节,我认为没有理由引入局部变量。

此外,您可以将Select抛入第二个Join的最后一个lambda中(同样,假设没有其他依赖于连接结果的操作),这将提供:

代码语言:javascript
复制
var categorizedProducts = product
    .Join(productcategory, p => p.Id, pc => pc.ProdId, (p, pc) => new { p, pc })
    .Join(category, ppc => ppc.pc.CatId, c => c.Id, (ppc, c) => new {
        ProdId = ppc.p.Id, // or ppc.pc.ProdId
        CatId = c.CatId
        // other assignments
    });

...and最后一次尝试向您推销查询语法,如下所示:

代码语言:javascript
复制
var categorizedProducts =
    from p in product
    join pc in productcategory on p.Id equals pc.ProdId
    join c in category on pc.CatId equals c.Id
    select new {
        ProdId = p.Id, // or pc.ProdId
        CatId = c.CatId
        // other assignments
    };

对于查询语法是否可用,您可能束手无策。我知道有些商店有这样的要求--通常是基于查询语法比点语法更有限的概念。还有其他原因,比如“如果我可以用点语法做更多的事情,为什么还要学习第二个语法呢?”正如这最后一部分所显示的-查询语法隐藏了一些细节,这使得它值得接受它带来的可读性改进:幸运的是,您必须准备的所有中间投影和标识符在查询语法版本中都不是最重要的-它们是背景毛绒。现在离开我的肥皂盒--不管怎样,谢谢你的问题。:)

票数 199
EN

Stack Overflow用户

发布于 2012-03-15 21:03:35

你所看到的就是你所得到的--这正是你所要求的,这里:

代码语言:javascript
复制
(ppc, c) => new { productproductcategory = ppc, category = c}

这是一个返回具有这两个属性的匿名类型的lambda表达式。

在你的CategorizedProducts中,你只需要遍历这些属性:

代码语言:javascript
复制
CategorizedProducts catProducts = query.Select(
      m => new { 
             ProdId = m.productproductcategory.product.Id, 
             CatId = m.category.CatId, 
             // other assignments 
           });
票数 12
EN

Stack Overflow用户

发布于 2016-08-04 23:01:58

看看我的项目中的示例代码

代码语言:javascript
复制
public static IList<Letter> GetDepartmentLettersLinq(int departmentId)
{
    IEnumerable<Letter> allDepartmentLetters =
        from allLetter in LetterService.GetAllLetters()
        join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroup
        from user in usersGroup.DefaultIfEmpty()// here is the tricky part
        join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID
        where allDepartment.ID == departmentId
        select allLetter;

    return allDepartmentLetters.ToArray();
}

在这段代码中,我连接了3个表,并从where子句中插入了连接条件

注意:服务类只是扭曲(封装)数据库操作

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9720225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档