在实际的应用场景中,一对多的关系是比较常见的,以文章和评论为例,一篇文章可能会存在多条评论。
下面以代码实例记录一对多形式的关系在EFCore中的使用:
控制台项目结构:
项目引用的程序集:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
1.在实体类中定义关系属性
文章实体类:
using System.Collections.Generic;
namespace OneToMore
{
/// <summary>
/// 文章表
/// </summary>
public class Article
{
public long Id { get; set; }
/// <summary>
/// 文章标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 文章内容
/// </summary>
public string Message { get; set; }
/// <summary>
/// 评论
/// </summary>
public List<Comment> Comments { get; set; } = new List<Comment>();
}
}
评论实体类:
namespace OneToMore
{
public class Comment
{
public long Id { get; set; }
/// <summary>
/// 评论内容
/// </summary>
public string Message { get; set; }
/// <summary>
/// 该评论对应的文章
/// </summary>
public Article C_Article { get; set; }
}
}
2.FluentAPI关系配置
文章实体类对应的配置
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace OneToMore
{
public class ArticleConfig : IEntityTypeConfiguration<Article>
{
public void Configure(EntityTypeBuilder<Article> builder)
{
builder.ToTable("T_Articles");
builder.Property(a => a.Title).HasMaxLength(100).IsUnicode().IsRequired();
builder.Property(a => a.Message).IsUnicode().IsRequired();
}
}
}
评论实体类对应的配置
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace OneToMore
{
public class CommentConfig : IEntityTypeConfiguration<Comment>
{
public void Configure(EntityTypeBuilder<Comment> builder)
{
builder.ToTable("T_Comments");
builder.Property(a => a.Message).IsUnicode().IsRequired();
builder.HasOne<Article>(c => c.C_Article).WithMany(a => a.Comments).IsRequired();
}
}
}
DbContext配置,用于定义数据库表和数据库链接等信息
using Microsoft.EntityFrameworkCore;
using System;
namespace OneToMore
{
public class MyDbContext : DbContext
{
public DbSet<Article> Articles { get; set; }
public DbSet<Comment> Comments { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
string connStr = "Server=.;Database=EFCoreDemo2;Trusted_Connection=True;MultipleActiveResultSets=true";
optionsBuilder.UseSqlServer(connStr);
//打印log日志
optionsBuilder.LogTo(msg =>
{
if (msg.Contains("CommandExecuting"))
{
Console.WriteLine(msg);
}
else
{
return;
}
});
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//从当前程序集中加载 实现了IEntityTypeConfiguration接口的实体配置类
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
}
3.使用关系操作
以上两步都操作完成后,先使用migration的相关命令在SqlServer数据库中创建对应的库和表(此操作在之前的文章中有说明),数据库创建完成后,在程序中就可以进行增删改查操作了。
新增一条文章,同时对该文章加两条评论。
using System;
namespace OneToMore
{
class Program
{
public static void Main(string[] args)
{
using (MyDbContext ctx = new MyDbContext())
{
Article a1 = new Article();
a1.Title = "张三被评为亚洲最牛逼的程序员";
a1.Message = "据报道..............................";
Comment c1 = new Comment { Message = "太牛了" };
Comment c2 = new Comment { Message = "吹吧,不可能" };
a1.Comments.Add(c1);
a1.Comments.Add(c2);
ctx.Articles.Add(a1);
ctx.SaveChanges();
}
}
}
}
在数据库中进行查询:
查询文章及文章对应的评论记录
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
namespace OneToMore
{
class Program
{
public static void Main(string[] args)
{
using (MyDbContext ctx = new MyDbContext())
{
Article article = ctx.Articles.Include(a => a.Comments).Single(a => a.Id == 7);
Console.WriteLine(article.Id);
Console.WriteLine(article.Title);
foreach (Comment item in article.Comments)
{
Console.WriteLine($"{item.Id},{item.Message}");
}
}
}
}
}
查询结果: