EntityFrameworkCore - 将新列添加到联接表

Posted

技术标签:

【中文标题】EntityFrameworkCore - 将新列添加到联接表【英文标题】:EntityFrameworkCore - Add new Column to Join table 【发布时间】:2021-12-13 15:00:51 【问题描述】:

我有两个实体:

public class Blog

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<Post> Posts  get; set; 

    public Blog()
    
        Posts = new List<Post>();
    


public class Post

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<Blog> Blogs  get; set; 

    public Post()
    
        Blogs = new List<Blog>();
    

它们之间的关系是多对多的。 EFCore 隐式创建表 BlogPost,如:

我想向此联接表添加新列 - 类型为 int 的顺序,但我的代码中没有实体 BlogPost。有没有办法添加(和使用)该列?

更新 #1

我尝试手动添加实体 BlogPost

public class BlogPost

    public Blog Blog  get; set; 
    public long BlogsId   get; set; 

    public Post Post  get; set; 
    public long PostsId  get; set; 


public class Post

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<Blog> Blogs  get; set; 
    public List<BlogPost> BlogPost  get; set; 
    public Post()
    
        Blogs = new List<Blog>();
    


public class Blog

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<Post> Posts  get; set; 
    public List<BlogPost> BlogPost  get; set; 

    public Blog()
    
        Posts = new List<Post>();
    


public class AppDbContext : DbContext

    public DbSet<Blog> Blogs  get; set;   
    public DbSet<Post> Posts  get; set; 
    public DbSet<BlogPost> BlogPost  get; set; 
    public AppDbContext(DbContextOptions options) : base(options)   

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Blog>()
            .HasMany(x => x.Posts)
            .WithMany(x => x.Blogs);
        modelBuilder.Entity<Blog>().HasMany(x => x.BlogPost).WithOne(x => x.Blog).HasForeignKey(x => x.BlogsId);
        modelBuilder.Entity<Post>().HasMany(x => x.BlogPost).WithOne(x => x.Post).HasForeignKey(x => x.PostsId);
        modelBuilder.Entity<BlogPost>().HasKey(x => new  x.BlogsId, x.PostsId );
    

但我得到一个错误:

System.InvalidOperationException: 'Cannot use table 'BlogPost' for entity type 'BlogPost' because it is used for entity type 'BlogPost (Dictionary)' and possible other entity types, but there is no linking关系。将外键添加到主键属性上的“BlogPost”,并指向另一个类型映射到“BlogPost”的实体上的主键。

【问题讨论】:

好吧,为什么不在您的代码中添加一个BlogPost 实体... EFCore 会去make something internally 处理它;您不妨将其外部化,创建一个实体并添加列。不要忘记调整导航属性,以便它们引用新的中间人实体 我很忙,但我收到了一个错误 -> 请参阅更新 #1 :) Blog 应该有一个ICollection&lt;BlogPost&gt; BlogPosts,Post 应该有相同的。您不再需要博客上的public ICollection&lt;Post&gt; Posts get; set; (例如)。如果您现在想知道博客有哪些帖子myBlog.BlogPosts.Select(bp =&gt; bp.Post) 引入数据库的本地实例并在 sql 中手动创建表。然后搭建该数据库并查看 EF 生成的内容。 【参考方案1】:

感谢Caius Jard,问题解决了:

public class Post

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<BlogPost> BlogPosts  get; set; 
    public Post()
    
        
    


public class Blog

    public long Id  get; set; 
    public string Content  get; set; 
    public ICollection<BlogPost> BlogPosts  get; set; 

    public Blog()
    
    


public class BlogPost

    public Blog Blog  get; set; 
    public long BlogsId   get; set; 

    public Post Post  get; set; 
    public long PostsId  get; set; 
    public int Order  get; set; 


public class AppDbContext : DbContext

    public DbSet<Blog> Blogs  get; set;   
    public DbSet<Post> Posts  get; set; 
    public DbSet<BlogPost> BlogPost  get; set; 
    public AppDbContext(DbContextOptions options) : base(options)   

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);
        
        modelBuilder.Entity<Blog>().HasMany(x => x.BlogPosts).WithOne(x => x.Blog).HasForeignKey(x => x.BlogsId);
        modelBuilder.Entity<Post>().HasMany(x => x.BlogPosts).WithOne(x => x.Post).HasForeignKey(x => x.PostsId);
        modelBuilder.Entity<BlogPost>().HasKey(x => new  x.BlogsId, x.PostsId );
    

【讨论】:

不确定解决这个答案的问题是什么。所有这些都是众所周知的 well documented 老式的多对多方式,EF Core 从版本一开始就支持。 是的,但是现在(据我所知)您可以建立多对多关系,而无需指定连接实体(在本例中为 BlogPost),EFCore 将处理这一点并制作连接表在数据库中。多对多关系的老式方法是使用连接实体创建两个一对多关系。问题是当您使用“新”方法但您想添加新列来加入实体时,您的代码中没有,因此您必须以老式方式重新创建该实体并向其添加新属性. 这并不完全正确。并且在official documentation 中也有介绍,以“附加数据可以存储在连接实体类型中,但为此最好创建一个定制的CLR 类型。提供的Post/@ 987654326@ 示例与您的Blog / Post 基本相同,但它们也显示了如何将这两种方法结合起来。

以上是关于EntityFrameworkCore - 将新列添加到联接表的主要内容,如果未能解决你的问题,请参考以下文章

将新列添加到 wordpress 数据库

将新列添加到 Oracle 表后生成主键值

如何将新列添加到权限表

如何将新列添加到现有表 symfony - orocommerce

如何将新列动态添加到 bigquery 中已存在的表..?

在 UDF 之后将新列附加到现有 PySpark 数据帧