如何使用种子方法为我的上下文创建初始数据?

时间:2016-01-13 02:58:13

标签: ef-code-first entity-framework-6

我正在尝试使用这样的种子方法;

        context.Reeves.AddOrUpdate(
            p => new { p.FirstName, p.LastName },
            new Reeve { FirstName = "A", LastName = "A" },
            new Reeve { FirstName = "B", LastName = "B" });
        context.SaveChanges();
        context.Districts.AddOrUpdate(
            p => p.Name,
            new District() { Name = "X", ReeveId = context.Reeves.First(r => r.FirstName == "A" && r.LastName == "A").Id },
            new District() { Name = "Y", ReeveId = context.Reeves.First(r => r.FirstName == "B" && r.LastName == "B").Id });
        context.SaveChanges();

我收到错误消息“INSERT语句与FOREIGN KEY约束冲突”FK_dbo.District_dbo.Reeve_Id“。冲突发生在数据库”ProjectTracking“,表”dbo.Reeve“,列'Id'。”

如果我更改下面的代码;

        context.Districts.AddOrUpdate(
            p => p.Name,
            new District() { Name = "X", Reeve = context.Reeves.First(r => r.FirstName == "A" && r.LastName == "A") },
            new District() { Name = "Y", Reeve = context.Reeves.First(r => r.FirstName == "B" && r.LastName == "B") });
        context.SaveChanges();

错误消息消失,但是当我检查区域表时,我看到所有ReeveId列都是0。

我的错误是什么,任何想法?

PS :我不想在District的AddOrUpdate方法中创建内联Reeve。就像是; context.Districts.AddOrUpdate(p => p.Name,new District(){Name =“X”,Reeve = new Reeve(){FirstName =“A”,LastName =“A”});

我的实体

public class Reeve
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName
    {
        get { return string.Format("{0} {1}", FirstName, LastName); }
    }
    public virtual District District { get; set; }
    public byte[] RowVersion { get; set; }
}

public class District
{
    public District()
    {
        Projects = new HashSet<Project>();
        ProjectRequests = new HashSet<ProjectRequest>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public int ReeveId { get; set; }
    public virtual Reeve Reeve { get; set; }
    public byte[] RowVersion { get; set; }
    public virtual ICollection<Project> Projects { get; set; }
    public virtual ICollection<ProjectRequest> ProjectRequests { get; set; }
}

实体配置

public class ReeveConfiguration : EntityTypeConfiguration<Reeve>
    {
        public ReeveConfiguration()
        {
            HasKey<int>(p => p.Id);
            Ignore(p => p.FullName);
            Property(p => p.FirstName).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("FullName", 1) { IsUnique = true })).HasMaxLength(50).IsRequired();
            Property(p => p.LastName).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("FullName", 2) { IsUnique = true })).HasMaxLength(50).IsRequired();
            Property(p => p.RowVersion).IsRowVersion();
        }
    }

public class DistrictConfiguration : EntityTypeConfiguration<District>
    {
        public DistrictConfiguration()
        {
            HasKey<int>(p => p.Id);
            HasRequired(p => p.Reeve).WithOptional(p => p.District);
            HasMany(p => p.Projects).WithRequired(p => p.District).HasForeignKey(p => p.DistrictId);
            HasMany(p => p.ProjectRequests).WithRequired(p => p.District).HasForeignKey(p => p.DistrictId);
            Property(p => p.Name).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = true })).HasMaxLength(100).IsRequired();
            Property(p => p.RowVersion).IsRowVersion();
        }
    }

我讨厌实体框架团队的1对1关系规则。委托实体必须与主要实体同名PK,委托实体PK也必须是FK。这一定是个玩笑。所有1对1的关系都不能像Person - &gt; PersonPhoto或Car - &gt;方向盘。我是对的,还是我误解了他们的逻辑。例如,我还有项目和项目请求实体,项目的请求和请求的项目可以为null我的意思是他们有0..1到0..1的关系,他们必须是自己的PK Id。如果我有具有Id主键字段的Entity基类,那该怎么样呢。我怎样才能从中获得我的1对1关系实体。

1 个答案:

答案 0 :(得分:0)

好的,我自己解决了我的问题。让我们再谈谈我的期望。我想为我的实体编写基类,第一步它只包含Id属性。另外我想控制我的外键名称,我不想自动为我做这件事。

也让我们谈谈收到的错误。我不能播种数据并收到错误,因为ef会自动为我创建外键,并且在区域实体ReeveId列中创建类似于其他数据列的内容。因此,当我使用现有的reeve设置District.ReeveId并保存更改时,抛出外键错误。

我在下面对我的代码进行了更改,以解决问题和我的期望;

  • 从区域实体删除ReeveId,因为没有必要
  • 添加HasRequired(p =&gt; p.Reeve).WithOptional(p =&gt; p.District).Map(m =&gt; m.MapKey(&#34; ReeveId&#34;));代码到我的分区配置

因此,两个表都包含主键的自己的Id列,分区也有外键的ReeveId列。结果,我的期望得到了满足。