这几天研究Asp.net5,也试着写了一些示例代码,因为网上的资料实在是太少了,所以在此把一些问题的解决方法记录下来,以备后查。
问题:
在EF7中,假如数据库已经存在,并且两个表具有外键关系,但是实际数据库中并没有加上这个约束,如何处理?
比如,我们有一个公司表,具有两个字段,id和name,如下所示:
public class Branch { /// <summary> /// 公司ID /// </summary> [Key] public string ID { get; set; } /// <summary> /// 公司名称 /// </summary> public string Name { get; set; } }
另外具有一个区域表,如下:
public class AreaInfo { [Key] public string AreaID { get; set; } public string BranchID { get; set; } public string Name { get; set; } public virtual Branch Branch { get; set; } }
区域表中,BranchID为逻辑上的外键,对应branch的ID。
如果需要通过代码来创建外键关系可以这样操作:
protected override void OnModelCreating(ModelBuilder modelBuilder) { var branchEntity = modelBuilder.Entity<Branch>().ToTable("BranchInfo"); var areaEntity = modelBuilder.Entity<AreaInfo>().ToTable("AreaInfo"); var id = branchEntity.Metadata.FindProperty("ID"); var branchKey = branchEntity.Metadata.FindKey(id); var branchProp = areaEntity.Metadata.FindProperty("BranchID"); areaEntity.Metadata.GetOrAddForeignKey(branchProp, branchKey, branchKey.DeclaringEntityType); base.OnModelCreating(modelBuilder); }
分别解释如下:
首先取得公司表的主键,
var id = branchEntity.Metadata.FindProperty("ID");
然后,根据主键属性取得主键:
var branchKey = branchEntity.Metadata.FindKey(id);
接着是取得主表,既区域表的外键属性:
var branchProp = areaEntity.Metadata.FindProperty("BranchID");
最后就是把外键属性和对应表的主键关联起来:
areaEntity.Metadata.GetOrAddForeignKey(branchProp, branchKey, branchKey.DeclaringEntityType);
这样,就通过代码建立起来了外键关系。
当然,最后通过
areaEntity.Metadata.AddForeignKey(branchProp, branchKey, branchKey.DeclaringEntityType);
这行代码添加关系也可以。