C# entityframework6 多对多
共享主键关系
概念:就是两个表共享相同的主键值,也就是说一表的主键值是另外一个表的外键值
我们创建两个实体类: 学生以及学生的联系方式
public class Students
{
public string Id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public virtual StudentContact StudentContact { get; set; }
}
public class StudentContact
{
public string Id { get; set; }
public string contactNumber { get; set; }
public virtual Students Student { get; set; }
}
HasOptional WithRequired
map 类
public class StudentsMap : EntityTypeConfiguration<Students>
{
public StudentsMap()
{
//表名称
ToTable("Students");
//主键
HasKey(t => t.Id);
Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(t => t.Name).HasColumnType("VARCHAR").HasMaxLength(50);
Property(t => t.Age);
HasOptional(t => t.StudentContact).WithRequired(l => l.Student);
}
}
public class StudentContactMap:EntityTypeConfiguration<StudentContact>
{
public StudentContactMap()
{
ToTable("StudentContact");
HasKey(x => x.Id);
Property(t => t.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None).HasColumnName("studentId");
Property(t => t.contactNumber);
}
}
上述中**HasColumnName(“studentId”)**表示数据库中StudentContact的主键名称是studentId
至于怎么在OnModelCreating 中注册map类请参考之前的文章
那么问题来了,在关系映射中,EF Code First最终是怎样决定谁是主体对象谁是依赖对象呢?
不难看出EF Code First是根据你的对象模型来判定的,例如我们上述用一下代码来判定学生和联系电话之间 的关系
HasOptional(t => t.StudentContact).WithRequired(l => l.Student);
这意思就是学生实体对于联系是可选的关系,但是联系对于学生却是必须的关系,所以我们得出结论:在这种关系中,最终学生将是主体对象而联系最终将是依赖对象。
想要设置级联删除,必须通过Fluent API进行级联删除,对于学生表可以这样操作
HasOptional(t => t.StudentContact).WithRequired(l => l.Student).WillCascadeOnDelete();
表结构
HasOptional WithOptionalPrincipal
public class Students
{
public string Id { get; set; }
public int Age { get; set; }
public string Name { get; set; }
public virtual StudentContact StudentContact { get; set; }
}
public class StudentContact
{
public string Id { get; set; }
public string contactNumber { get; set; }
public virtual Students Student { get; set; }
}
map 类
public class StudentsMap : EntityTypeConfiguration<Students>
{
public StudentsMap()
{
//表名称
ToTable("Students");
//主键
HasKey(t => t.Id);
Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(t => t.Name).HasColumnType("VARCHAR").HasMaxLength(50);
Property(t => t.Age);
HasOptional(t => t.StudentContact).WithOptionalPrincipal(l => l.Student).WillCascadeOnDelete();
}
}
WithOptionalPrincipal 使得Student作为主体
public class StudentContactMap:EntityTypeConfiguration<StudentContact>
{
public StudentContactMap()
{
ToTable("StudentContact");
HasKey(x => x.Id);
Property(t => t.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
Property(t => t.contactNumber);
}
}
表结构
此时StudentContact表中Id为主键,Student_Id为外键