本文作者:小黑黑

[EFCore]一对一、一对多、多对多关系

小黑黑 12个月前 ( 04-22 ) 682 抢沙发
[EFCore]一对一、一对多、多对多关系摘要: 一、一对一关系例子:每篇博客都对应这一张缩略图,每一张缩略图都对应一片博客。/// <summary>/// 博客类/// <...

一、一对一关系
例子:每篇博客都对应这一张缩略图,每一张缩略图都对应一片博客。

/// <summary>
/// 博客类
/// </summary>
public class Blog
{
    /// <summary>
    /// ID
    /// </summary>
    public int BlogId { get; set; }

    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 缩略图
    /// </summary>
    public virtual BlogImage BlogImage { get; set; }
}

/// <summary>
/// 缩略图类
/// </summary>
public class BlogImage
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 缩略图的路径
    /// </summary>
    public string Path { get; set; }

    /// <summary>
    /// 对应的博客ID
    /// </summary>
    public int BlogId { get; set; }

    /// <summary>
    /// 对应的博客
    /// </summary>
    public virtual Blog Blog { get; set; }
}

/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(option
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        //一对一关系,从blog开始配置
        modelBuilder.Entity<Blog>()
                    .HasOne(p => p.BlogImage)   //每一篇博客对应一张缩略图
                    .WithOne(p => p.Blog)       //每一张缩略图对应一片博客
                    .HasForeignKey<BlogImage>(p => p.BlogId);   //设置外键

        ////一对一关系,从blogimage开始配置
        modelBuilder.Entity<BlogImage>()
                    .HasOne(p => p.Blog)        //每个缩略图对应一篇博客
                    .WithOne(p => p.BlogImage)  //每篇博客对应一张缩略图
                    .HasForeignKey<BlogImage>(p => p.BlogId);   //设置外键

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Blog> Blogs { get; set; }

    public DbSet<BlogImage> BlogImages { get; set; }
}

二、一对多关系

例子:一个博客里面有多个文章,多篇文章属于一个博客。

/// <summary>
/// 博客类
/// </summary>
public class Blog
{
    /// <summary>
    /// ID
    /// </summary>
    public int BlogId { get; set; }

    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 文章
    /// </summary>
    public virtual List<Post> Posts { get; set; }

    /// <summary>
    /// 缩略图
    /// </summary>
    public virtual BlogImage BlogImage { get; set; }
}

/// <summary>
/// 文章表
/// </summary>
public class Post
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 内容
    /// </summary>
    public string Content { get; set; }

    /// <summary>
    /// 博客ID
    /// </summary>
    public int BlogId { get; set; }

    /// <summary>
    /// 博客
    /// </summary>
    public virtual Blog Blog { get; set; }
}

/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        //一对多关系,从blog开始配置,一个博客可以有多篇文章,多篇文章属于一个博客
        modelBuilder.Entity<Blog>()
                    .HasMany(p => p.Posts)    //一个博客可以有多篇文章
                    .WithOne(p => p.Blog)       //多篇文章属于一个博客
                    .HasForeignKey(p => p.BlogId);      //设置外键

        //一对多关系,从post开始配置,一个博客可以有多篇文章,多篇文章属于一个博客
        modelBuilder.Entity<Post>()
                    .HasOne(p => p.Blog)        //多篇文章属于一个博客
                    .WithMany(p => p.Posts)     //一个博客有多篇文章
                    .HasForeignKey(p => p.BlogId);      //设置外键


        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Blog> Blogs { get; set; }

    public DbSet<Post> Posts { get; set; }
}

三、多对多关系

例子:一篇文章可以有多个标签,一个标签下可以有多篇文章,由于关系型数据库不能直接设置多对多关系,我们可以使用第三张表,通过使用一堆多关系来设置多对多的关系。

/// <summary>
/// 文章表
/// </summary>
public class Post
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 内容
    /// </summary>
    public string Content { get; set; }

    /// <summary>
    /// 博客ID
    /// </summary>
    public int BlogId { get; set; }

    /// <summary>
    /// 文章标签表
    /// </summary>
    public virtual ICollection<PostTag> PostTag { get; set; }
}

/// <summary>
/// 标签表
/// </summary>
public class Tag
{
    /// <summary>
    /// Id
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// 标签名称
    /// </summary>
    public string TagName { get; set; }

    /// <summary>
    /// 文章标签表
    /// </summary>
    public virtual ICollection<PostTag> PostTag { get; set; }
}

/// <summary>
/// 文章标签表
/// </summary>
public class PostTag
{
    /// <summary>
    /// 文章ID
    /// </summary>
    public int PostId { get; set; }

    /// <summary>
    /// 文章
    /// </summary>
    public virtual Post Post { get; set; }

    /// <summary>
    /// 标签ID
    /// </summary>
    public int TagId { get; set; }

    /// <summary>
    /// 标签
    /// </summary>
    public virtual Tag Tag { get; set; }
}

/// <summary>
/// 数据库上下文
/// </summary>
public class BloggingDbContext : DbContext
{

    public BloggingDbContext(DbContextOptions<BloggingDbContext> options) : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        //多对多关系,首先设置复合组主键,通过postid和tagid可以确定这条数据在posttag的唯一性
        modelBuilder.Entity<PostTag>()
                    .HasKey(p => new { p.PostId, p.TagId });

        //配置posttag和post,posttag和tag表的一对多关系
        modelBuilder.Entity<PostTag>()
                    .HasOne(p => p.Post)
                    .WithMany(p => p.PostTag);

        modelBuilder.Entity<PostTag>()
                    .HasOne(p => p.Tag)
                    .WithMany(p => p.PostTag);


        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Post> Posts { get; set; }

    public DbSet<PostTag> PostTags { get; set; }
}


分享到: 网站分享代码

发表评论

快捷回复:

评论列表 (暂无评论,682人围观)参与讨论

还没有评论,来说两句吧...