tnblog
首页
视频
资源
登录

Code First 配置外键 一对多 多对多

5414人阅读 2021/3/26 17:54 总访问:94417 评论:0 收藏:0 手机
分类: MVC
 
 
? 配置外键
 
 
一:导航属性
外键字段在模型中没有,没法自己去控制联和查询只能使用导航属性
//子表
namespace Model
{
    [Table("UserInfo")]
    public class UserInfo
    {
        [Key]
        public int id { get; set; }
        [Required]
        public string UserName { get; set; }
        [StringLength(32), Required]
        public string Number { get; set; }
        //1外键添加
        public virtual Userparent userparent { get; set; }
    }
}
主表
namespace Model
{
   public class Userparent
    {
        public int Id { get; set; }
        public string Father { get; set; }
        public string Mother { get; set; }
        public virtual List<UserInfo> users { get; set; }
    }
}
二:导航属性+自定义属性
   1:    //[Table("UserInfo")]
    public class UserInfo
    {
        [Key]
        public int id { get; set; }
        [Required]
       public string UserName { get; set; }
        [StringLength(32), Required]
        public string Number { get; set; }
 
        //1外键
        [ForeignKey("userparent")]
        public int UserparentId { get; set; }
        public virtual Userparent userparent { get; set; }
    }
 
 
  
  2:
  [Table("UserInfo")]
    public class UserInfo
   {
       [Key]
        public int id { get; set; }
        [Required]
       public string UserName { get; set; }
        [StringLength(32), Required]
       public string Number { get; set; }
 
        //2外键  
        public int UserparentId { get; set; }
            [ForeignKey("UserparentId ")]
        public virtual Userparent userparent { get; set; }
    }
 
三:在上下文对象中重写模型创建,使用fluent api
级联删除
Ef code first默认开启级联删除,从你删除的表,当做主表,把相关的数据全部删除。
 
  //方法一对多来配置
   //虚方法
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
                 //一对多来配置后面不加.WillCascadeOnDelete(false)默认开启联表删除
            modelBuilder.Entity<UserInfo>().HasRequired(a => a.userparent).WithMany(a => a.users).HasForeignKey(a => a.UserparentId);
 
            //方法多对一来配置
            modelBuilder.Entity<多的对象名称>().HasMany(a => a.users 多的对象需配置的链接字段 ).WithRequired(a => a.userparent 少的对象须配置的链接字段).HasForeignKey(a => a.UserparentId 少的字段最终确认链接字段 );
 
            modelBuilder.Entity<Userparent>().HasMany(a => a.users).WithRequired(a => a.userparent).HasForeignKey(a => a.UserparentId).WillCascadeOnDelete(false);
 
            //如果关闭级联删除在后面加.WillCascadeOnDelete(false)
            //fales表示的是关闭联级删除
            //true表示的是打开
                        //全部关闭
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
 
                        //生成的表去掉自动生成的后缀名s
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
 
    级联删除的关闭或者开启
    1:只删除或者关闭某两个表的关系
  modelBuilder.Entity<Userparent>().HasMany(a => a.users).WithRequired(a => a.userparent).HasForeignKey(a => a.UserparentId).WillCascadeOnDelete(false);
 }
建议用法:在需要的表加.WillCascadeOnDelete(false); 如果用全局可能会造成数据不小心全部删除

 
  [Table("UserInfo")]
    public class UserInfo
    {
        [Key]
        public int id { get; set; }
        [Required]
        public string UserName { get; set; }
        [StringLength(32), Required]
        public string Number { get; set; }
 
        //3利用虚方法外键
        public int UserparentId { get; set; }
        public virtual Userparent userparent { get; set; }
}
 
 
namespace DAL
{
    public class ShopContext : DbContext
    {
        public ShopContext()
            : base("name=ShopEetities")
        {
 
        }
        //虚方法
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //方法一配置1的一方
            //modelBuilder.Entity<UserInfo>().HasRequired(a => a.userparent).WithMany(a => a.users).HasForeignKey(a => a.UserparentId);
            //方法二配置多的一方
            //modelBuilder.Entity<多的对象名称>().HasMany(a => a.users 多的对象需配置的链接字段 ).WithRequired(a => a.userparent 少的对象须配置的链接字段).HasForeignKey(a => a.UserparentId 少的字段最终确认链接字段 );
            modelBuilder.Entity<Userparent>().HasMany(a => a.users).WithRequired(a => a.userparent).HasForeignKey(a => a.UserparentId);      
        }
        public DbSet<UserInfo> UserInfo { get; set; }
        public DbSet<Userparent> Userparent { get; set; }
    }
}
 
 
配置多对多
 
学生    课程
1       多
多      1
 
多对多关系,应该有一个中间表,用于关联,关联表至少两个字段,就是两张表的id
 
 
 
l  导航属性
只需要在相关联的表增加对方的表名就可以自动生成关系如
    public class UserInfo
    {
        [Key]
        public int id { get; set; }
        [Required]
        public string UserName { get; set; }
        [StringLength(32), Required]
        public string Number { get; set; }
        //3利用虚方法外键
        public int UserparentId { get; set; }
        public virtual Userparent userparent { get; set; }
//相关联的字段
        public virtual List<Sub 相关联的表名> Coress { get; set; }
}
 
   public  class Sub
    {
        public int Id { get; set; }
        public string Cores { get; set; }
//相关联的字段
        public virtual List<UserInfo 相关联的表名> userinfos { get; set; }
 
    }
l  使用fluentApi
更灵活,关联表的表名,两个外键可以自己灵活控制
l  配置多对多
 
//配置生成的一张新表表示关系  
1.   ToTable(自定义新表表名); 
2.   MapLeftKey(自定义用户的关联字段); 
3.   MapRightKey(自定义成绩关联的字段);
 
            modelBuilder.Entity<UserInfo>().HasMany(a => a.Coress).WithMany(a => a.userinfos).Map(a =>
            {
                a.ToTable("UserInfo_Sub");
                a.MapLeftKey("UserId");
                a.MapRightKey("SubId");
            });
 
l  自己维护
最灵活的,不仅可以自己控制表名外键名,还可以自己维护对象已经其他其他字段。
(多对多其实可以理解成两个1对多。可以拆分成两个多对多)
 
 
? 数据库迁移
Enable-Migrations启用数据库迁移
Enable-Migrations –EnableAutomaticMigrations 启动自动迁移
Update-Database 更新到数据库


评价
.
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
欢迎加群交流技术