实体框架 - 配置标识密钥

时间:2015-09-04 12:57:39

标签: sql-server entity-framework entity-framework-6

我在配置EF映射时遇到了一些问题。

我有以下类(每个字典可以有0个,1个或多个DictionaryDomain个对象):

public class Dictionary
{
  public virtual ICollection<DictionaryDomain> Domains { get; set; }
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
}

public class DictionaryDomain
{
  public virtual Dictionary Dictionary { get; set; }
  public virtual int DictionaryId { get; set; } // I have added this after error described below
  public virtual Domain Domain { get; set; }
  public virtual int Id { get; set; }
}

public class Domain
{
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
}

当我删除域名(伪代码)时

Dictionary d = GetDictionary();
d.Domains.remove(some_object);

我收到了一个错误:

  

“DictionaryDomain_Dictionary”AssociationSet中的关系处于“已删除”状态。给定多重约束,相应的'DictionaryDomain_Dictionary_Source'也必须处于'已删除'状态。

所以我将DictionaryId添加到DictionaryDomain类作为键的一部分,并以这种方式配置了类:

        modelBuilder.Entity<Dictionary>()
            .HasKey(e => e.Id);
        modelBuilder.Entity<Dictionary>()
            .Property(e => e.Name).IsRequired().HasMaxLength(200);

        modelBuilder.Entity<DictionaryDomain>()
            .HasRequired(e => e.Dictionary);
            // Added from this line
        modelBuilder.Entity<DictionaryDomain>()
            .HasKey(e => new { e.Id, e.DictionaryId });
        modelBuilder.Entity<DictionaryDomain>()
            .Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<DictionaryDomain>()
            .Property(e => e.DictionaryId).HasColumnName("Dictionary_Id");
            // Till this line
        modelBuilder.Entity<DictionaryDomain>()
            .HasRequired(e => e.Domain);

        modelBuilder.Entity<Domain>()
            .HasKey(e => e.Id);
        modelBuilder.Entity<Domain>()
            .Property(e => e.Name).IsRequired().HasMaxLength(200);                

但是在我添加了迁移后,我得到了一些奇怪的迁移:

    public override void Up()
    {
        DropIndex("dbo.DictionaryDomains", new[] { "Domain_Id" });
        DropColumn("dbo.DictionaryDomains", "Id");
        RenameColumn(table: "dbo.DictionaryDomains", name: "Domain_Id", newName: "Id");
        DropPrimaryKey("dbo.DictionaryDomains");
        AlterColumn("dbo.DictionaryDomains", "Id", c => c.Int(nullable: false, identity: true));
        AddPrimaryKey("dbo.DictionaryDomains", new[] { "Id", "Dictionary_Id" });
        CreateIndex("dbo.DictionaryDomains", "Id");
    }

这不是我的预期(我希望只重新创建主键)。

我不知道我做错了什么。也许我对EF的工作方式不够了解,但任何提示都会受到赞赏。

由于

1 个答案:

答案 0 :(得分:0)

解决方法是将DomainId添加到类DictionaryDomain,并将此字段添加到组合键。

类看起来像这样:

public class DictionaryDomain
{
    public virtual Dictionary Dictionary { get; set; }
    public virtual int DictionaryId { get; set; }
    public virtual Domain Domain { get; set; }
    public virtual int DomainId { get; set; }
    public virtual int Id { get; set; }
}

和映射:

        modelBuilder.Entity<DictionaryDomain>()
            .HasRequired(e => e.Dictionary);
        modelBuilder.Entity<DictionaryDomain>()
            .HasKey(e => new {e.Id, e.DictionaryId, e.DomainId});
        modelBuilder.Entity<DictionaryDomain>()
            .Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<DictionaryDomain>()
            .Property(e => e.DictionaryId).HasColumnName("Dictionary_Id");
        modelBuilder.Entity<DictionaryDomain>()
            .Property(e => e.DomainId).HasColumnName("Domain_Id");
        modelBuilder.Entity<DictionaryDomain>()
            .HasRequired(e => e.Domain);

之后我得到了正确的迁移:

        DropPrimaryKey("dbo.DictionaryDomains");
        AddPrimaryKey("dbo.DictionaryDomains", new[] { "Id", "Dictionary_Id", "Domain_Id" });

之后从收集中删除按预期工作 - 现在:)