【问题标题】:Joining 3 tables and using a left outer join with linq in EF Core 3.1.1在 EF Core 3.1.1 中加入 3 个表并使用带有 linq 的左外连接
【发布时间】:2020-12-24 22:56:38
【问题描述】:

我有 3 张桌子,NoticesUsersLikes。如果用户喜欢此通知,我想获取所有带有用户名和信息的通知。

到目前为止,我有这段代码,但它多次返回一个通知(每个喜欢一个):

return context.notices
        .GroupJoin(context.Users, notice => notice.CreatedBy, user => user.Id, (notice, users) => new { notice, users })
        .SelectMany(group => group.users.DefaultIfEmpty(), (group, user) =>
        new
        {
            group.notice,
            user
        })
        .GroupJoin(context.Likes, noticeDto => noticeDto.notice.Id, like => like.ItemId, (noticeDto, likes) => new { noticeDto, likes })
        .SelectMany(group => group.likes.DefaultIfEmpty(), (group, like) =>
        new NoticeDto
        {
            CreatedByName = (group.noticeDto.user == null ? "" : group.noticeDto.user.FullName),
            Id = group.noticeDto.notice.Id,
            Liked = like.CreatedBy == userId,
        });

我也试过这个代码..但我得到一个错误:

return context.notices
                .GroupJoin(context.Users, notice => notice.CreatedBy, user => user.Id, (notice, users) => new { notice, users })
                .SelectMany(group => group.users.DefaultIfEmpty(), (group, user) =>
                new
                {
                    group.notice,
                    user
                })
                .GroupJoin(context.Likes, noticeDto => noticeDto.notice.Id, like => like.ItemId, (noticeDto, likes) => new { noticeDto, likes })
                .Select((group) =>
                new NoticeDto
                {
                    CreatedByName = (group.noticeDto.user == null ? "" : group.noticeDto.user.FullName),
                    Id = group.noticeDto.notice.Id,                 
                    Liked = group.likes != null ? group.likes.Any(w => w.CreatedBy == userId) : false,
                });

这是我得到的错误:

处理 LINQ 表达式 'DbSet .LeftJoin( 外部:数据库集 .AsQueryable(), 内部:notice => notice.CreatedBy, 外键选择器:用户 => 用户 ID, innerKeySelector: (notice, user) => new { 通知=通知, 用户 = 用户 }) .GroupJoin( 外部:数据库集, 内部:noticeDto => noticeDto.notice.Id, outerKeySelector: like => like.ItemId, innerKeySelector: (noticeDto, likes) => new { noticeDto = noticeDto, 喜欢=喜欢 })'
'NavigationExpandingExpressionVisitor' 失败。这可能表示 EF Core 中存在错误或限制。

谁能帮我实现我需要的东西?..谢谢。

通知

    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }

用户

 public Guid Id { get; set; }
 public string FullName{ get; set; }

喜欢

    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid ItemId { get; set; }

【问题讨论】:

    标签: sql entity-framework linq entity-framework-core linq-to-entities


    【解决方案1】:

    Like 的 ItemId 是 Notice 的 ID? Notice's and Like 的 CreatedBy 是用户的 ID?

    如果是这样,试试这个。

    return context.notices.Include(x => x.Users)
                          .Include(x => x.Likes)
                          .Include("Likes.Users");
    

    数据库

    结果

    已编辑

    由于你没有外键和关系,那么你可以试试这个

    var users = context.Users;
            
    return context.notices.Select(x => new Notice() 
    {
         Id = x.Id,
         CreatedBy = x.CreatedBy, 
         Users = users.Where(y => y.Id == x.CreatedBy).FirstOrDefault(), 
         Likes = context.Likes.Where(y => y.ItemId == x.Id)
                        .Select(y => new Likes()
                        {
                            Id = y.Id,
                            CreatedBy = y.CreatedBy,
                            ItemId = y.ItemId,
                            Users = users.Where(z => z.Id == y.CreatedBy).FirstOrDefault()
                        }).ToList()
    });
    

    【讨论】:

    • 感谢@Asherguru 的评论。你的第一句话是正确的。但我没有使用 CreatedBy 或 ItemId 作为外键 .. 它只是 guid。所以我认为不可能包括这个。为此,我需要为其提供链接表。我认为没有必要。删除用户时,我也不需要关心点赞和通知。
    • 可以检查“已编辑”。无论如何,如果您在删除用户时不需要关注点赞和通知,您只需在用户表中添加新列“IsDeleted”即可。当用户被删除时,更改 IsDeleted = 1。然后在 Notice 的 UI 和 Likes 的 UI 中,用户名将类似于“Name1(已删除)”
    • 是的..你可以像这样实现它..但我不认为它有效..你从数据库中获得了所有的喜欢。然后对于每个喜欢你的用户(我相信这会导致每个喜欢单独调用)
    • 已更新。你可以检查一下。
    • o.O 这看起来不错.. 这怎么可能?使用 Select 时不需要联接?此代码将创建一个对 DB 的查询?
    猜你喜欢
    • 2021-08-25
    • 2021-05-06
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多