Linq和左加入

时间:2019-06-12 14:15:14

标签: c# linq join

我有以下型号:

public class UserPage
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
    public string Path { get; set; }
    public string Icon { get; set; }
}

public class UserPageSetting
{
    public int UserId { get; set; }
    public int PageId { get; set; }
    public bool Active { get; set; } = true;
    public bool Published { get; set; } = true;
    public DateTime? Modified { get; set; }

    public virtual UserPage UserPage { get; set; }
}

UserPage集合有5条记录,UserPageSetting有1条记录。我需要一个包含5条记录和不存在记录的默认值的结果。

我尝试这样做:

var list = (from userPage in _dbContext.UserPages
           join userPageSetting in _dbContext.UserPageSettings on userPage.Id equals userPageSetting.PageId
           into gj
            from subUserPageSetting in gj.DefaultIfEmpty()
            where subUserPageSetting.UserId == userId
           select new UserPageSettingDto { Active = subUserPageSetting.Active, Modified = subUserPageSetting.Modified, Id = userPage.Id, Icon = userPage.Icon, IsSelected = userPage.IsSelected,
               Name = userPage.Name, Path = userPage.Path, Published = subUserPageSetting.Published
           }).ToList();

但是结果我只看到一条记录。我的代码有什么问题?

1 个答案:

答案 0 :(得分:0)

这是一个示例,该示例说明在联接失败时如何进行左联接并创建默认的UserPageSetting。这将返回5条记录;每个UserPage 1个。其中之一将具有成功的联接,并用Active = true

表示
void Main()
{
    var inner = new List<UserPage> {
        new UserPage { Id = 1, Name = "One" },
        new UserPage { Id = 2, Name = "Two" },
        new UserPage { Id = 3, Name = "Three" },
        new UserPage { Id = 4, Name = "Four" },
        new UserPage { Id = 5, Name = "Five" }};

    var outer = new List<UserPageSetting> {
        new UserPageSetting { UserId = 1, PageId = 1, Active = true, Published = true }};

    var joined = inner
        .GroupJoin(outer, i => i.Id, o => o.PageId, (i, o) => o
               .Select(x => new { Inner = i, Outer = x })
               .DefaultIfEmpty(new { Inner = i, Outer = new UserPageSetting {UserId = i.Id, PageId = i.Id, Active = false, Published = false } }))
        .SelectMany(x => x)
        //.Where(x => x.Outer == -1) -- include if you only want to see the join misses
        ;

    foreach (var x in joined)
    {
        Console.WriteLine($"UserPage({x.Inner.Id}, {x.Inner.Name}) joined to UserPageSetting({x.Outer.UserId}, {x.Outer.Active})");
    }
}

这将输出以下内容:

UserPage(1, One) joined to UserPageSetting(1, True)
UserPage(2, Two) joined to UserPageSetting(2, False)
UserPage(3, Three) joined to UserPageSetting(3, False)
UserPage(4, Four) joined to UserPageSetting(4, False)
UserPage(5, Five) joined to UserPageSetting(5, False)