配置外键
一:导航属性
外键字段在模型中没有,没法自己去控制联和查询只能使用导航属性
//子表
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; }
}
}
二:导航属性+自定义属性
//[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; }
}
[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默认开启级联删除,从你删除的表,当做主表,把相关的数据全部删除。
//方法一对多来配置
//虚方法
// 建议用法:在需要的表加.WillCascadeOnDelete(false); 如果用全局可能会造成数据不小心全部删除
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);
}
[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
导航属性
只需要在相关联的表增加对方的表名就可以自动生成关系如
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; }
}
使用fluentApi
配置多对多
//配置生成的一张新表表示关系
//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");
});
自己维护
最灵活的,不仅可以自己控制表名外键名,还可以自己维护对象已经其他其他字段。
(多对多其实可以理解成两个1对多。可以拆分成两个多对多)
数据库迁移
Enable-Migrations启用数据库迁移
Enable-Migrations –EnableAutomaticMigrations 启动自动迁移
Update-Database 更新到数据库