【问题标题】:Entity Framework Core: get related dataEntity Framework Core:获取相关数据
【发布时间】:2021-12-03 19:29:00
【问题描述】:

在我正在开发的应用程序中,我的用户可以拥有播放列表。他们可以访问自己的播放列表(然后他们将成为其所有者)或与他们所属的团队相关的播放列表。我的实体如下所示(Id 是 Guid 类型,继承自实体 AuditEntity):

public class Team : AuditEntity
{
    public Team()
    {
        Playlists = new HashSet<Playlist>();
    }

    public string TeamName { get; set;}

    public Guid OwnerId { get; set; }
    public virtual AppUser Owner { get; set; }

    public ICollection<TeamsAppUsers> Members { get; set; }
    public ICollection<Playlist> Playlists { get; private set; }
}

public class Playlist : AuditEntity
{
    public string PlaylistName { get; set; }    

    public Guid OwnerId { get; set; }
    public virtual AppUser Owner { get; set; }

    public Team Team { get; set; }
}

public class TeamsAppUsers
{
    public Guid AppUserId { get; set; }
    public AppUser Member { get; set; }

    public Guid TeamId { get; set; }
    public Team Team { get; set; }
}

我需要所有播放列表(并且只有一次),其中用户要么是所有者,要么是与播放列表相关的团队成员。

我只有OwnerId

var playlists = await _context.Playlists
                              .Where(pl => pl.OwnerId == userId)
                              .ToListAsync()

如何扩展此声明,使其还包括用户是相关团队成员的播放列表?

【问题讨论】:

  • 您可以在PlayList 中添加TeamId 属性,然后在TeamId 上加入PlayListTeamAppUsers
  • 为什么要在查询中将 OwnerId guid 转换为字符串?是因为 userId 是“看起来像 guid 的字符串”吗?如果是这样,您应该在查询之前将userId 转换为 guid,而不是每次查询时都将数百个 db guid 转换为字符串
  • @GertArnold 如果 EF 可以通过在 Where 中的引用看到它需要什么,是否还需要它?
  • .Where(pl =&gt; pl.OwnerId == userId || pl.Team.Members.Any(m =&gt; m.SOMETHING == userId) - 有些东西可能是 AppUserId,您的命名约定与播放列表(OwnerId/Owner)中使用的命名约定有所不同。相当肯定 EF 会将其转换为协调的 EXISTS

标签: c# linq entity-framework-core asp.net-core-3.1


【解决方案1】:

您可以将代码移到您的上下文中并使用 EntityFramework,我允许自己在几个地方编辑您的类型以便能够建立模型构建关系,如下所示:


    public class PlaylistsDbContext : DbContext
    {
        DbSet Teams { get; set; }
        DbSet Playlists { get; set; }
        DbSet AppUsers { get; set; }
        //Not needed
        DbSet TeamAppUsers { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity().HasKey(k => k.Id);
            modelBuilder.Entity().HasKey(k => k.Id);
            modelBuilder.Entity().HasKey(k => k.AppUserId);
          
            //Not needed
            modelBuilder.Entity().HasKey(k => new { k.AppUserId, k.TeamId });

            modelBuilder.Entity().HasMany(x => x.Playlists).WithOne(y => y.Team);
            modelBuilder.Entity()
                .HasOne(x => x.Owner)
                .WithMany(y => y.PlayLists)
                .HasPrincipalKey(k => k.AppUserId)
                .HasForeignKey(f => f.OwnerId);
            modelBuilder.Entity()
                .HasOne(x => x.Team)
                .WithMany(y => y.Playlists)
                .HasPrincipalKey(p => p.Id)
                .HasForeignKey(f => f.TeamId);

            //These relationship tables can be omitted, as entity framework can handle that for You
            //Then you can also drop the explicit foreign key fields
            
            base.OnModelCreating(modelBuilder);
        }

        public List GetUserPlaylists(Guid userId)
        {
            return Playlists.Include(x => x.Owner).Include(y => y.Team)
                .Where(z => z.Owner.AppUserId == userId
                                || z.Team.Members.Any(m => m.AppUserId == userId))
                .Distinct()
                .ToList();
        }
    }
    

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2021-06-13
    • 2023-04-02
    • 2019-02-23
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    相关资源
    最近更新 更多