我在配置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的关系处于'Deleted'状态。考虑到多重约束,相应的'DictionaryDomain_Dictionary_Source'也必须处于'Deleted'状态。
所以我将DictionaryId
添加到DictionaryDomain
类中作为key的一部分,并以这种方式配置类:
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的工作原理了解不够,但如果有任何建议,我将不胜感激。谢谢
解决方案是将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" });
在此之后,从集合中删除工作按预期进行:)