我正在使用实体框架6 ,当我从数据库逆向工程我的架构时,我发现没有生成多个FK关系。它让我疯了。如果我手动添加它们,我会在尝试插入时开始获取密钥违规错误。把它们带回去,一切正常。
架构:
当我查看我的RemarketingCase对象时,我没有看到地址,债务人或Notes的任何集合,也没有参考资产或摘要。然而,当我查看Status对象时,我有一个ICollection RecordHistories / CaseHistories。我查看历史表,我参考了Status表,但没有引用RemarketingCase表。
这真是令人厌烦,因为我正在尝试处理那些不存在的对象图!它迫使我通过一次一个地按照正确的顺序处理RemarketingCase及其所有关系的添加,因此SQL不会弹出参照完整性错误。
带FK参考的样本(由EF生成):
public partial class Status
{
public Status()
{
this.CaseHistories = new List<CaseHistory>();
}
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public virtual ICollection<CaseHistory> CaseHistories { get; set; }
}
public class StatusMap : EntityTypeConfiguration<Status>
{
public StatusMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.Title)
.IsRequired()
.IsFixedLength()
.HasMaxLength(15);
this.Property(t => t.Description)
.IsRequired()
.HasMaxLength(50);
// Table & Column Mappings
this.ToTable("Status");
this.Property(t => t.Id).HasColumnName("Id");
this.Property(t => t.Title).HasColumnName("Title");
this.Property(t => t.Description).HasColumnName("Description");
}
}
由EF生成的没有FK参考的样本:
public partial class RemarketingCase
{
public int LoanId { get; set; }
public int RequestId { get; set; }
public string VIN { get; set; }
public int RemarketingCaseId { get; set; }
public string CaseId { get; set; }
public string CaseNumber { get; set; }
public string AssetId { get; set; }
public System.DateTime Created { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> Updated { get; set; }
public string UpdatedBy { get; set; }
}
public class RemarketingCaseMap : EntityTypeConfiguration<RemarketingCase>
{
public RemarketingCaseMap()
{
// Primary Key
this.HasKey(t => new { t.LoanId, t.RequestId, t.VIN });
// Properties
this.Property(t => t.LoanId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.RequestId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(t => t.VIN)
.IsRequired()
.HasMaxLength(25);
this.Property(t => t.RemarketingCaseId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(t => t.CaseId)
.HasMaxLength(50);
this.Property(t => t.CaseNumber)
.HasMaxLength(50);
this.Property(t => t.AssetId)
.HasMaxLength(50);
this.Property(t => t.CreatedBy)
.IsRequired()
.HasMaxLength(50);
this.Property(t => t.UpdatedBy)
.HasMaxLength(50);
// Table & Column Mappings
this.ToTable("RemarketingCase");
this.Property(t => t.LoanId).HasColumnName("LoanId");
this.Property(t => t.RequestId).HasColumnName("RequestId");
this.Property(t => t.VIN).HasColumnName("VIN");
this.Property(t => t.RemarketingCaseId).HasColumnName("RemarketingCaseId");
this.Property(t => t.CaseId).HasColumnName("CaseId");
this.Property(t => t.CaseNumber).HasColumnName("CaseNumber");
this.Property(t => t.AssetId).HasColumnName("AssetId");
this.Property(t => t.Created).HasColumnName("Created");
this.Property(t => t.CreatedBy).HasColumnName("CreatedBy");
this.Property(t => t.Updated).HasColumnName("Updated");
this.Property(t => t.UpdatedBy).HasColumnName("UpdatedBy");
}
}
手动添加参考样本:
public partial class RemarketingCase
{
public RemarketingCase()
{
this.Addresses = new List<Address>();
this.Debtors = new List<Debtor>();
this.Notes = new List<Note>();
this.RecordHistories = new List<RecordHistory>();
this.CaseHistories = new List<CaseHistory>();
}
public int LoanId { get; set; }
public int RequestId { get; set; }
public string VIN { get; set; }
public int RemarketingCaseId { get; set; }
public string CaseId { get; set; }
public string CaseNumber { get; set; }
public string AssetId { get; set; }
public System.DateTime Created { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> Updated { get; set; }
public string UpdatedBy { get; set; }
// manually added...
public virtual ICollection<Address> Addresses { get; set; }
public virtual ICollection<Debtor> Debtors { get; set; }
public virtual ICollection<Note> Notes { get; set; }
public virtual ICollection<RecordHistory> RecordHistories { get; set; }
public virtual ICollection<CaseHistory> CaseHistories { get; set; }
public virtual Asset Asset { get; set; }
public virtual Summary Summary { get; set; }
}
这是我手动添加FK时出现的错误:
测试方法AutoPay.Test.Remarketing.DatabaseChange.InsertAsset扔了 exception:System.Data.Entity.Infrastructure.DbUpdateException:An 更新条目时发生错误。查看内部异常 细节。 ---&GT; System.Data.Entity.Core.UpdateException:错误 更新条目时发生。查看内部异常 细节。 ---&GT; System.InvalidOperationException:依赖属性 在ReferentialConstraint中映射到存储生成的列。 专栏:&#39; RemarketingCaseId&#39;。
答案 0 :(得分:1)
通过稍微更改数据库设计,将可怕的ID字段添加为PK,此错误消失了。虽然这违反了SQL规范化,但它就是这样。不幸的是,我还没有找到让EF正确处理复合PK的方法。 (参见我的问题的评论。)