c# - LINQ left join ordered with empty right-items at the end

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

我对 LINQ 和 Entity Framework 的了解很少,我边学边学......

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

结果集应包含来自 GroupView所有 项目连接项在开头(按 GroupSequence 表定义的顺序)和未连接项在末尾(按 Id 项的 GroupView 定义的顺序)。

即...

[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在中继器上提示...

The entity or complex type 'DevModel.GroupSequence' cannot be constructed in a LINQ to Entities query

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 行添加?我做错了什么?

最佳答案

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

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 
};

关于c# - LINQ left join ordered with empty right-items at the end,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28961146/

相关文章:

c# - 在 C# 中捕获网络流量

c# - 我应该如何在异步/等待操作中使用静态方法/类?

c# - 组合两个 linq 表达式以注入(inject)导航属性

.net - 如何在 Linq 中执行 SQL Like %?

c# - HttpChannelRequest WaitForReply 上的 WCF 代理 ProcessGetResponseWebException

entity-framework - 如何在实体设计器中映射每个类型的表(TPT)继承?

c# - 可以将委托(delegate)分配给匿名方法或 lambda,但不能分配给方法

c# - 同时使用属性路由和基于约定的路由与 Web API 和 MVC

c# - 改进 Linq-XML 到对象查询

asp.net-mvc - Entity Framework MVC Controller