EntityFramework Core2.0 多对多关系配置

​ 在EF6.0 中,多对多关系配置时,系统会自动生成第三张表,来将两张有互相约束关系的表联系起来,但是在EF Core2.0中,我们需要手动建立第三张表,比如说有两个模型Passage.cs和Category.cs,若想建立两者之间的多对多关系,我们就需要借助第三张表PassageCategory来实现:

public class Passage
{
    //文章编号
    [Key]
    public long PassageId { get; set; }

    //标题
    public string Title { get; set; }

    //描述
    public string Description { get; set; }

    //内容
    public string Content { get; set; }

    //发布时间
    public DateTime PublishTime { get; set; }

    //最后编辑时间
    public DateTime LastEditTime { get; set; }

    //文章分类(使用技术等)
    public virtual IList<PassageCategory> PassageCategories { get; set; }
}
public class Category
{
    [Key]
    public int CategoryId { get; set; }

    [MaxLength(50)]
    public string CategoryName { get; set; }

    public virtual IList<PassageCategory> PassageCategories { get; set; }
}

public class PassageCategory
{
    public int CategoryId { get; set; }

    public Category Category { get; set; }

    public long PassageId { get; set; }

    public Passage Passage { get; set; }
}

然后添加 FluentAPI 配置,在配置多对多关系时,必须指定级联删除。

​ 先说一下EFCore的几种级联模式:

  • Cascade ​ 依赖的实体也一并被删除。这种级联行为只对被上下文跟踪到的实体有效。数据库里也需要设置相应的级联,确保没有被上下文跟踪到的数据也具备同样的行为。如果你通过EF来创建数据库,那么EF会为你设置好数据库的级联。
  • Restrict ​ 删除操作不会作用在依赖实体上,依赖实体保持不变。
  • SetNull ​ 依赖实体的外键被设为null。这种级联行为只对被上下文跟踪到的实体有效。数据库里也需要设置相应的级联,确保没有被上下文跟踪到的数据也具备同样的行为。如果你通过EF来创建数据库,那么EF会为你设置好数据库的级联。
  • ClientSetNull ​ EFCore2.0引入了一种叫作ClientSetNull的默认行为。它具有SetNull的语义,兼有Restrict的行为。从我们的经验来看,对于被跟踪的实体和数据库来说,它是最被期待也是最有用的一种行为。

​ 在为被跟踪的实体设置级联关系时,DeleteBehavior.Restrict已经成为历史。

​ 添加一个新类 PassageCategoryMap.cs 该类继承自 IEntityTypeConfiguration 接口

    public class PassageCategoryMap : IEntityTypeConfiguration<PassageCategory>
    {
        /// <summary>
        /// PassageCategories FluentAPI配置
        /// 
        /// 添加复合主键、配置多对多关系
        /// </summary>
        /// <param name="builder"></param>
        public void Configure(EntityTypeBuilder<PassageCategory> builder)
        {
            //添加复合主键
            builder.HasKey(t => new { t.PassageId, t.CategoryId });

            ///<summary>
            ///
            /// 配置Passage与PassageCategories的一对多关系
            /// 
            /// EFCore中,新增默认级联模式为ClientSetNull
            /// 
            /// 依赖实体的外键会被设置为空,同时删除操作不会作用到依赖的实体上,依赖实体保持不变,同下
            /// 
            /// </summary>

            //配置Passage与PassageCategories的一对多关系
            builder.HasOne(t => t.Passage).WithMany(p => p.PassageCategories).HasForeignKey(t => t.PassageId).OnDelete(DeleteBehavior.SetNull);

            //配置Category与PassageCategories的一对多关系
            builder.HasOne(t => t.Category).WithMany(p => p.PassageCategories).HasForeignKey(t => t.CategoryId).OnDelete(DeleteBehavior.SetNull);
        }
    }

​ 然后在 DbContext 类中,重写 OnModelCreating 方法添加 FluentAPI 配置

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    //查找所有FluentAPI配置
    var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);

    //应用FluentAPI
    foreach(var type in typesToRegister)
    {
        //dynamic使C#具有弱语言的特性,在编译时不对类型进行检查

        dynamic configurationInstance = Activator.CreateInstance(type);
        builder.ApplyConfiguration(configurationInstance);
    }
}

​ 然后添加数据迁移,更新数据库,就完成了多对多关系数据库的配置。

转载请标明出处:EntityFramework Core2.0 多对多关系配置

作者:Niko

欢迎访问我的主页:vlins.cn

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇