LINQ左边的连接以最右边的空右项排序

时间:2015-03-10 10:22:18

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

我对LINQ和实体框架的理解很少,而且我在学习的同时也在学习......

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

结果集应该具有<{strong>全部来自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会抱怨......

  

实体或复杂类型&#39; DevModel.GroupSequence&#39;不能在LINQ to Entities查询中构造

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

1 个答案:

答案 0 :(得分:1)

您需要将过滤器移动到左连接条件,因为当item为空时它将为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 
};