C# 使用实体框架核心为数据库播种多对多关系

C# 使用实体框架核心为数据库播种多对多关系,c#,entity-framework,asp.net-core,entity-framework-core,C#,Entity Framework,Asp.net Core,Entity Framework Core,我使用Entity Framework Core创建了多对多关系,但有几个问题: 如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗 如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么。下面的一些事情似乎很奇怪。我更喜欢简单地创建BlogPost对象并将它们添加到上下文中的BlogPost中 var blog1 = new Blog() { Name = "ABC

我使用Entity Framework Core创建了多对多关系,但有几个问题:

如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗

如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么。下面的一些事情似乎很奇怪。我更喜欢简单地创建BlogPost对象并将它们添加到上下文中的BlogPost中

var blog1 = new Blog() { Name = "ABC" };
blog1.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
var blog2 = new Blog() { Name = "123" };
blog2.BlogPosts.Add(new BlogPost { BlogId = blog2.Id, PostId = post1.Id });
var blog3 = new Blog() { Name = "XYZ" };
blog3.BlogPosts.Add(new BlogPost { BlogId = blog3.Id, PostId = post2.Id });
dbContext.SaveChanges();
另外,如果我只关心从一个方向查询博客和帖子,那么我是否必须向博客和帖子添加列表导航属性,如示例中所示。i、 博客>帖子,不需要博客帖子

如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗

不!不会痛的!这样做没有问题!然后您可以按如下方式使用:

context.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
context.Set<BlogPost>().Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

}

public class Tag
{
    public string TagId { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}
如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么

如果您不想将
BlogPosts
公开为
DbSet
,则可以执行以下操作:

context.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
context.Set<BlogPost>().Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

}

public class Tag
{
    public string TagId { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}
然后在DbContext中:

class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany()
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany()
            .HasForeignKey(pt => pt.TagId);
    }
}
class MyContext:DbContext
{
公共DbSet Posts{get;set;}
公共DbSet标记{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(t=>new{t.PostId,t.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Post)
.有很多
.HasForeignKey(pt=>pt.posted);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.有很多
.HasForeignKey(pt=>pt.TagId);
}
}
如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗

不!不会痛的!这样做没有问题!然后您可以按如下方式使用:

context.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
context.Set<BlogPost>().Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

}

public class Tag
{
    public string TagId { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}
如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么

如果您不想将
BlogPosts
公开为
DbSet
,则可以执行以下操作:

context.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
context.Set<BlogPost>().Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

}

public class Tag
{
    public string TagId { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}
然后在DbContext中:

class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany()
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany()
            .HasForeignKey(pt => pt.TagId);
    }
}
class MyContext:DbContext
{
公共DbSet Posts{get;set;}
公共DbSet标记{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(t=>new{t.PostId,t.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Post)
.有很多
.HasForeignKey(pt=>pt.posted);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.有很多
.HasForeignKey(pt=>pt.TagId);
}
}
如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗

不可以。显式连接实体(
BlogPost
)与其他实体一样,因此您可以为其添加(或不添加)
DbSet

如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么。下面的一些事情似乎很奇怪。我更喜欢简单地创建BlogPost对象并将它们添加到上下文中的BlogPost中

var blog1 = new Blog() { Name = "ABC" };
blog1.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
var blog2 = new Blog() { Name = "123" };
blog2.BlogPosts.Add(new BlogPost { BlogId = blog2.Id, PostId = post1.Id });
var blog3 = new Blog() { Name = "XYZ" };
blog3.BlogPosts.Add(new BlogPost { BlogId = blog3.Id, PostId = post2.Id });
dbContext.SaveChanges();
即使没有exposed
DbSet
属性,也可以始终使用
Set
方法访问相应的
DbSet

另外,如果我只关心从一个方向查询博客和帖子,那么我是否必须向博客和帖子添加列表导航属性,如示例中所示。i、 博客>帖子,不需要博客帖子

导航属性不是必需的-请参阅EF核心文档主题。你可以省略其中任何一个。你甚至不需要一个流畅的关系配置,因为一切都是按惯例进行的。但是,如果您使用示例中的fluent配置,请确保使用
WithMany()
方法,而不传递lambda/string导航属性(因为您没有该属性)

如果我将DbSet BlogPosts添加到DbContext中,即使在示例中它们没有这样做,这会有什么影响吗

不可以。显式连接实体(
BlogPost
)与其他实体一样,因此您可以为其添加(或不添加)
DbSet

如果我不将DbSet添加到DbContext中,那么创建一个Blog,然后在创建数据库种子时向其添加多篇文章的正确方法是什么。下面的一些事情似乎很奇怪。我更喜欢简单地创建BlogPost对象并将它们添加到上下文中的BlogPost中

var blog1 = new Blog() { Name = "ABC" };
blog1.BlogPosts.Add(new BlogPost { BlogId = blog1.Id, PostId = post1.Id });
var blog2 = new Blog() { Name = "123" };
blog2.BlogPosts.Add(new BlogPost { BlogId = blog2.Id, PostId = post1.Id });
var blog3 = new Blog() { Name = "XYZ" };
blog3.BlogPosts.Add(new BlogPost { BlogId = blog3.Id, PostId = post2.Id });
dbContext.SaveChanges();
即使没有exposed
DbSet
属性,也可以始终使用
Set
方法访问相应的
DbSet

另外,如果我只关心从一个方向查询博客和帖子,那么我是否必须向博客和帖子添加列表导航属性,如示例中所示。i、 博客>帖子,不需要博客帖子


导航属性不是必需的-请参阅EF核心文档主题。你可以省略其中任何一个。你甚至不需要一个流畅的关系配置,因为一切都是按惯例进行的。但是,如果您使用示例中的fluent配置,请确保使用
WithMany()
方法,而不传递lambda/string导航属性(因为您没有该属性)

你回答了我的问题,我会把它标对,但我认为你误解了问题2。我的意思是,如果我选择不将BlogPosts实体添加为DbSet,那么在播种数据库时创建BlogPosts的正确方法是什么。我算出来了:blog1.BlogPosts.Add(newblogpost{PostId=post1.Id})。甚至不需要设置