我是.NET Core的新手,并且正在使用EF Core 2
我的域对象都是从基类派生的,基类上有一些审核字段,可以根据需要在enumerate
上进行设置:
(以下简化)
SaveChanges
在添加迁移时,出现错误:
public abstract class AuditableEntity
{
public DateTime CreatedOn { get; set; }
[ForeignKey("CreatedBy")]
public Guid? CreatedByWebUserId { get; set; }
public WebUser CreatedBy { get; set; }
public DateTime? UpdatedOn { get; set; }
[ForeignKey("UpdatedBy")]
public Guid? UpdatedByWebUserId { get; set; }
public WebUser UpdatedBy { get; set; }
public DateTime? DeletedOn { get; set; }
[ForeignKey("DeletedBy")]
public Guid? DeletedByWebUserId { get; set; }
public WebUser DeletedBy { get; set; }
}
Unable to determine the relationship represented by navigation property
'Address.CreatedBy' of type 'WebUser'. Either manually configure the
relationship, or ignore this property using the '[NotMapped]' attribute or by
using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
是从Address
派生的类之一:
(以下简化)
AuditableEntity
但是,我有几个对象使用与上面类似的相同“代理程序和时间戳”对模式,并且工作正常,例如:
public class Address : AuditableEntity
{
public Guid Id { get; set; }
public string Nickname { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string StateProvince { get; set; }
public string PostalCode { get; set; }
public string CountryCode { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
错误总是来自 public DateTime? VerifiedOn { get; set; }
[ForeignKey("VerifiedBy")]
public Guid? VerifiedByWebUserId { get; set; }
public WebUser VerifiedBy { get; set; }
,如果我从“地址”中删除基类,则一切正常(这意味着这些字段已成功应用于我的15个以上其他域对象)。
该问题似乎源于Address
对WebUser
的引用:
(以下简化)
Address
创建这些引用的正确方法是优先保留FK约束(而不是保持导航能力)?
答案 0 :(得分:2)
该问题与基类的使用无关(如果删除基类,也会发生同样的情况,但是将其属性复制到Address
类中),但是多重交叉这两个类之间的引用。
按照惯例,EF Core尝试自动“配对”两个实体的导航属性以形成单个关系,这种关系在大多数情况下都是成功的。但是,在这种情况下,WebUser
具有Address
类型的导航属性,而Address
类具有WebUser
类型的导航属性(实际上为3)。
由于它们都通过ForeignKey
数据注释具有关联的FK属性,因此EF Core应该能够正确地将它们标识为不同的一对多关系,但事实并非如此。不仅会因所讨论的异常而失败,而且不会为WebUser
创建FK关系。
如果基类仅包含1种WebUser
类型的导航属性,则一切正常,因此,我很不幸地假设您遇到了一些当前的EF Core错误。
作为一种变通办法,直到他们修复它,我建议通过使用OnModelCreating
并添加以下代码来使用流利的API显式配置有问题的关系:
var auditableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(t => t.ClrType.IsSubclassOf(typeof(AuditableEntity)));
var webUserNavigations = new[] { nameof(AuditableEntity.CreatedBy), nameof(AuditableEntity.DeletedBy), nameof(AuditableEntity.UpdatedBy) };
foreach (var entityType in auditableEntityTypes)
{
modelBuilder.Entity(entityType.ClrType, builder =>
{
foreach (var webUserNavigation in webUserNavigations)
builder.HasOne(typeof(WebUser), webUserNavigation).WithMany();
});
}
即对于从AuditableEntity
派生的每个实体类,我们显式配置3个WebUser
参考导航属性以映射到3个独立的一对多关系,而没有逆集合导航属性。完成此操作后,EF Core便不会出现正确映射WebUser.Address
FK关联的问题。