【问题标题】:Linq Lambda join breaks when joining a table加入表时,Linq Lambda 连接中断
【发布时间】:2016-07-18 16:08:55
【问题描述】:

我对 lambda 比较陌生。我正在尝试创建一个从我的数据库中提取产品并加入作者表的连接。但是我的数据库中的某些产品没有作者,例如产品包。因此,查询不会提取这些记录。

有没有办法提取在 linq lambda 中有或没有作者的所有产品的记录。类似于内连接或右连接?这是我的数据库/查询:

数据库

产品

+-----------------------------------------+--------+----+---------+
|                FullName                 | TypeId | Id |   Sku   |
+-----------------------------------------+--------+----+---------+
| The Matrix                              |      1 | 23 | MAT     |
| Lord Of The Rings                       |      1 | 22 | LOTR    |
| Package: Lord of the rings & The Matrix |      2 | 33 | LOTRMAT |
+-----------------------------------------+--------+----+---------+

作者分配

+--------+----+----------+
| TypeId | Id | AuthorId |
+--------+----+----------+
|      1 | 23 |        1 |
|      1 | 22 |        2 |
+--------+----+----------+

作者

+----------+------------------+
| AuthorId |      Author      |
+----------+------------------+
|        1 | The Wachowskis   |
|        2 | J. R. R. Tolkien |
+----------+------------------+

查询

        var allitems = _contentService.Products.Select(
            x => new {x.FullName, x.TypeId, x.Id, x.Sku})
            .Join(
                _contentService.AuthorAssignments,
                x => new {x.TypeId, x.Id},
                y => new {y.TypeId, y.Id},
                (x, y) =>
                    new
                    {
                        x.Sku,
                        x.FullName,
                        x.Id,
                        x.TypeId,
                        y.AuthorId
                    })
            .Join(
                _contentService.Authors,
                authId => authId.AuthorId ,
                auth => auth.Id,
                (authId, auth) =>
                    new
                    {
                        authId.Sku,
                        authId.FullName,
                        authId.Id,
                        authId.TypeId,
                        authId.Image,
                        auth.Author
                    });

这给了我这样的结果:

+-------------------+--------+----+------+------------------+
|     FullName      | TypeId | Id | Sku  |      Author      |
+-------------------+--------+----+------+------------------+
| The Matrix        |      1 | 23 | MAT  | The Wachowskis   |
| Lord Of The Rings |      1 | 22 | LOTR | J. R. R. Tolkien |
+-------------------+--------+----+------+------------------+

当这是我想要完成的事情时

+-----------------------------------------+----------+----+---------+------------------+
|                FullName                 |   TypeId | Id |   Sku   |      Author      |
+-----------------------------------------+----------+----+---------+------------------+
| The Matrix                              |        1 | 23 | MAT     | The Wachowskis   |
| Lord Of The Rings                       |        1 | 22 | LOTR    | J. R. R. Tolkien |
| Package: Lord of the rings & The Matrix |        2 | 33 | LOTRMAT | null             |
+-----------------------------------------+----------+----+---------+------------------+

看起来像这样,因为包不包含 1 个作者记录,它只是忽略了它。非常感谢任何帮助。

更新

抱歉,我忘了说我正在使用 NHibernate。因此未实现 groupjoins :(

【问题讨论】:

  • 您肯定需要左外连接,但坦率地说,很难使用连接和方法语法。如果您使用查询语法,更改将是微不足道的。
  • 所以问题是,你想要一个有效的查询还是你坚持方法语法(你称之为 lambda)?
  • 是的,我只想留在 Lambda 表达式中。
  • 然后看看GroupJoinSelectManyDefaultIfEmpty方法。我怀疑这里有人会为你做那种艰难的转变。祝你好运。
  • 你没有说你是否使用了EntityFramework,但假设你是,你应该在你的模型中设置navigation properties,然后这将是微不足道的。此外,从 AuthorAssignments 表中删除 id 字段。它不是必需的,只会给您带来问题。使用导航属性,您的查询变为var allitems=_db.Products.Include(p=>p.Authors);(是的,您的所有 29 行代码都被替换为那个 sn-p!)

标签: c# mysql linq join lambda


【解决方案1】:

这是 lambda 表达式 方法语法中的查询:

var allitems = _contentService.Products
    .Select(x => new {x.FullName, x.TypeId, x.Id, x.Sku})
    .GroupJoin(_contentService.AuthorAssignments,
        p => p.Id,
        aa => aa.Id,
        (p, aa) => new 
        { 
            p.Sku, 
            p.FullName, 
            p.Id, 
            p.TypeId, 
            AuthorId = aa.Select(x => x.AuthorId).FirstOrDefault()
        })
    .GroupJoin(_contentService.Authors,
        p => p.AuthorId,
        a => a.Id,
        (p, a) => new 
        { 
            p.FullName, 
            p.TypeId, 
            p.Id,
            p.Sku, 
            Author = a.Select(x => x.Author).FirstOrDefault()
        });

输出:

+--------------------------------+--------+----+---------+------------------+
|            FULLNAME            | TYPEID | ID |   SKU   |      AUTHOR      |
+--------------------------------+--------+----+---------+------------------+
|                                |        |    |         |                  |
| The Matrix                     | 1      | 23 | MAT     | The Wachowskis   |
|                                |        |    |         |                  |
| Lord Of The Rings              | 1      | 22 | LOTR    | J. R. R. Tolkien |
|                                |        |    |         |                  |
| Package: Lord of the rings & T | 2      | 33 | LOTRMAT | null             |
| he Matrix                      |        |    |         |                  |
+--------------------------------+--------+----+---------+------------------+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多