【问题标题】:Entity Framework Core Relationship Issue (code first) - duplicate columns实体框架核心关系问题(代码优先) - 重复列
【发布时间】:2021-11-02 11:45:27
【问题描述】:

我正在使用代码优先方法(EF Core 5 + SQL Server)开发一个应用程序。

我有一些包含数据的表,然后是 2 个连接表。

我遇到的问题是 EF 以某种方式在连接表中创建了重复的列。例如。 SessionId 和 SessionId1。我不知道为什么。

这里有一些来自代码的sn-ps以便更好地理解:

会话表:

    public class Session
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public long EventId { get; set; }

        public virtual Event Event { get; set; }
        public virtual UserSessionRole UserSessionRole { get; set; }
    }

事件表:

    public class Event
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public DateTime Date { get; set; }

        public virtual List<Session> Sessions { get; set; }
    }

连接表:

    public class UserSessionRole
    {
        public long Id { get; set; }
        public long SessionId { get; set; }
        public long RoleId { get; set; }
        public long UserId { get; set; }
        public long EventId { get; set; }

        public virtual Session Session { get; set; }
        public virtual Event Event { get; set; }
        public virtual Role Role { get; set; }
        public virtual User User { get; set; }
    }

我使用 fluent API 来定义关系等。例如。会话设置:

// Map entities to tables  
            modelBuilder.Entity<Session>().ToTable("sessions");

            // Configure Primary Keys  
            modelBuilder.Entity<Session>().HasKey(u => u.Id);
            modelBuilder.Entity<Session>().Property(p => p.Id).ValueGeneratedOnAdd();

            // Configure indexes  
            modelBuilder.Entity<Session>().HasIndex(u => u.EventId);

            // Configure columns  
            modelBuilder.Entity<Session>().Property(ug => ug.Name).HasColumnType("nvarchar(255)").IsRequired();
            modelBuilder.Entity<Session>().Property(ug => ug.Description).HasColumnType("nvarchar(255)").IsRequired();
            modelBuilder.Entity<Session>().Property(ug => ug.DateTime).HasColumnType("datetime").IsRequired();
            modelBuilder.Entity<Session>().Property(ug => ug.VonageSessionId).HasColumnType("nvarchar(255)").IsRequired();

            // Configure relationships  
            modelBuilder.Entity<Session>().HasMany<UserSessionRole>().WithOne(r => r.Session).HasForeignKey(u => u.SessionId).OnDelete(DeleteBehavior.NoAction);

用户会话角色:

            // Map entities to tables  
            modelBuilder.Entity<UserSessionRole>().ToTable("usersessionroles");

            // Configure Primary Keys  
            modelBuilder.Entity<UserSessionRole>().HasKey(x => new { x.RoleId, x.SessionId, x.UserId });
            modelBuilder.Entity<UserSessionRole>().Property(p => p.Id).ValueGeneratedOnAdd();

在这种情况下,我得到重复的 SessionId 和重复的 RoleId,但不是 EventId。

任何人都知道我配置错了什么或者是否有任何我不知道的技巧?

【问题讨论】:

    标签: c# sql-server entity-framework-core


    【解决方案1】:

    我最终通过从 Session 中删除 Event 并明确定义 WithMany 关系解决了这个问题。我也是从另一边做的。

    这行得通:

    modelBuilder.Entity<UserSessionRole>().HasOne(x => x.Event).WithMany(s => s.UserSessionRoles).HasForeignKey(u => u.EventId).OnDelete(DeleteBehavior.NoAction);
    
    

    这没有:

    modelBuilder.Entity<UserSessionRole>().HasOne(x => x.Event).WithMany(s).HasForeignKey(u => u.EventId).OnDelete(DeleteBehavior.NoAction);
    

    【讨论】:

      【解决方案2】:

      使用您的代码 sn-p 我可以理解的是您正在尝试创建一对多关系的事件和会话表,如果是这样我们可以避免连接表 (UserSessionRole) 并将 RoleId、UserId 带到会话表。

      public class Event
      {
          public long Id { get; set; }
          public string Name { get; set; }
          public DateTime Date { get; set; }
      
          public virtual ICollection<Session> Sessions { get; set; }
      }
      public class Session
      {
          public long Id { get; set; }
          public string Name { get; set; }
          public long RoleId { get; set; }
          public long UserId { get; set; }
          public long EventId { get; set; }
      
          public virtual Event Event { get; set; }
          public virtual Role Role { get; set; }
          public virtual User User { get; set; }
      }
      

      如果你需要连接表(UserSessionRole)那么关系变成Event : UserSessionRole(一对多)和UserSessionRole : Session(一对一)就会变成这样,

      public class Event
      {
          public long Id { get; set; }
          public string Name { get; set; }
          public DateTime Date { get; set; }
      
          public virtual ICollection<UserSessionRole>SessionRoles{ get; set; }
      }
      
      // One to Many Relation between Event and UserSessionRole
      
      public class UserSessionRole
      {
          public long Id { get; set; }
          public long EventId { get; set; }
          public long RoleId { get; set; }
          public long UserId { get; set; }
          public long SessionId { get; set; }
      
          public virtual Session Session { get; set; }
          public virtual Event Event { get; set; }
          public virtual Role Role { get; set; }
          public virtual User User { get; set; }
      }
      
      // One to One Relation between UserSessionRole and Session
      
      public class Session
      {
          public long Id { get; set; }
          public string Name { get; set; }
      
          public virtual Session Session { get; set; }
      }
      

      【讨论】:

        【解决方案3】:

        由于你有连接表并且在 Session 和 Event 之间建立了多对多关系,所以从 Session 中移除 EventId,并且由于你使用的是 Net5,你也可以将事件集合添加到 Session 中

        public class Session
            {
                public long Id { get; set; }
                public string Name { get; set; }
              
                public virtual ICollection<Event> Events { get; set; }
                public virtual ICollection <UserSessionRole> UserSessionRoles { get; set; }
            }
        Event table:
        
            public class Event
            {
                public long Id { get; set; }
                public string Name { get; set; }
                public DateTime Date { get; set; }
        
                public virtual ICollection <UserSessionRole> UserSessionRoles { get; set; }
                public virtual List<Session> Sessions { get; set; }
            }
        

        【讨论】:

        • 我试过了,但没有解决问题,谢谢。
        • @Skynet 你必须相应地更新你的 Fluent API 并再次进行初始化迁移。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 2019-05-06
        • 2012-10-11
        • 2017-07-05
        • 2012-10-26
        • 1970-01-01
        相关资源
        最近更新 更多