【问题标题】:LINQ left join ordered with empty right-items at the endLINQ 左连接在最后用空的右项排序
【发布时间】:2015-03-10 10:22:17
【问题描述】:

我对 LINQ 和 Entity Framework 的了解很少,我正在学习中...

我正在尝试编写一个查询,该查询从名为GroupView视图 中获取信息,并在名为GroupSequence 的表上进行左连接...然后信息将是由<asp:Repeater> 使用。

结果集应该有 所有 来自 GroupView 的项目,开头是连接项目(按GroupSequence 表定义的顺序),最后是非连接项目(由GroupView 项的Id 定义的顺序)。

也就是说……

[GroupView]             |    [GroupSequence]
[Id]  [Name]   [Calc]   |    [Id]  [GroupId]  [UserId]  [Sequence]
1     Group 1  23       |    1     1          1         3
2     Group 2  34       |    2     2          1         2
3     Group 3  45       |    3     3          1         1
4     Group 4  56
5     Group 5  67

预期结果...

[Id]  [Name]   [Calc]
3     Group 3  45
2     Group 2  34
1     Group 1  23
4     Group 4  56
5     Group 5  67

如果我执行以下操作,尽管使用了DefaultIfEmpty,我得到的只是与序列相关联的 3 个组。但是页面显示,即使它只有 3 行...

from @group in context.GroupViews
join seq in context.GroupSequences on @group.Id equals seq.GroupId into groupSeq
from item in groupSeq.DefaultIfEmpty()
where item.UserId == 1
orderby item.Sequence
select new { Id = @group.Id, Name = @group.Name, Calc = @group.Calc };

如果我执行以下操作,中继器上的 .DataBind 会抱怨...

无法在 LINQ to Entities 查询中构造实体或复杂类型“DevModel.GroupSequence”

from @group in context.GroupViews
join seq in context.GroupSequences on @group.Id equals seq.GroupId into groupSeq
from item in groupSeq.DefaultIfEmpty(new GroupSequence { Id = @group.Id, UserId = 1, Sequence = @group.Id + 1000 })
where item.UserId == 1
orderby item.Sequence
select new { Id = @group.Id, Name = @group.Name, Calc = @group.Calc };

基于this question and accepted answer,我也尝试过像这样使用DTO...

class GroupViewSequenceDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? Calc { get; set; }
}

from @group in context.GroupViews
join seq in context.GroupSequences on @group.Id equals seq.GroupId into groupSeq
from item in groupSeq.DefaultIfEmpty(new GroupSequence { Id = @group.Id, UserId = 1, Sequence = @group.Id + 1000 })
where item.UserId == 1
orderby item.Sequence
select new GroupViewSequenceDTO { Id = @group.Id, Name = @group.Name, Calc = @group.Calc };

但是我还是遇到了和以前一样的错误(无法构造)

问题...

如何编写此查询,以便转发器显示所有 5 行,前 3 行按顺序排列,最后 2 行添加?我做错了什么?

【问题讨论】:

    标签: c# linq entity-framework visual-studio-2010 join


    【解决方案1】:

    您需要将过滤器移动到左连接条件,因为当item 为空时它将为假。

    from @group in context.GroupViews
    from seq in context.GroupSequences.Where(x => @group.Id == x.GroupId && x.UserId == 1).DefaultIfEmpty()
    orderby seq.Sequence ?? int.MaxValue
    select new GroupViewSequenceDTO 
    {
       Id = @group.Id, 
       Name = @group.Name, 
       Calc = @group.Calc 
    };
    

    【讨论】:

    • 谢谢@Magnus - 小错误(item.UserId 应该是x.UserId)。我正在获取所有 5 行,但两个空项位于列表的开头
    • 然后订购物品descending
    • 但这将按降序排列前 3 个项目(对不起,我是新手……我相信我最终可以工作,我只是在挣扎在手工编写数据处理程序十年后,让我的头脑进入一种完全不同的编码方式)
    • 如果序列是int,你可以将它设置为int.MaxValue,而它是null
    • 或者一般你可以试试orderby new { ISN = seq.Sequence == null ? 1 : 0, seq.Sequence }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    相关资源
    最近更新 更多