我首先遇到继承代码问题。 我的基类看起来像这样:
public abstract class BaseEntity
{
public DateTime? DateCreated { get; set; }
public string UserCreatedId { get; set; }
public DateTime? DateModified { get; set; }
public string UserModifiedId { get; set; }
public virtual UserState UserCreated { get; set; }
public virtual UserState UserModified { get; set; }
}
并且我已经继承了它,这给了我一个名为UserCreated_userStateId和UserModified_UserStateId的附加列。所以我尝试这样流畅的API:
modelBuilder.Entity<BaseEntity>().HasOptional(x => x.UserCreated).WithMany().HasForeignKey(x => x.UserCreatedId);
modelBuilder.Entity<BaseEntity>().HasOptional(X => X.UserModified).WithMany().HasForeignKey(x => x.UserModifiedId);
但是这给了我错误:“在模型生成期间检测到一个或多个验证错误:
BaseEntity :: EntityType'BaseEntity'没有定义键。定义此EntityType的键。 BaseEntities:EntityType:EntitySet'BaseEntities'基于类型'BaseEntity',没有定义键。“如何避免定义键并只更改属性的映射?我在派生类中有键。
答案 0 :(得分:1)
您可以将基类配置包装在泛型方法中,并为每个具体实体类型调用它。
static void ConfigureBaseEntity<TDerived>(EntityTypeConfiguration<TDerived> entityTypeConfiguration) where TDerived : BaseEntity
{
// your base class configuration
entityTypeConfiguration.HasOptional(x => x.UserCreated).WithMany().HasForeignKey(x => x.UserCreatedId);
entityTypeConfiguration.HasOptional(X => X.UserModified).WithMany().HasForeignKey(x => x.UserModifiedId);
}
调用每个具体实体类型
public class DerivedEntity : BaseEntity
{
public int Id { get; set; }
}
//...
ConfigureBaseEntity(modelBuilder.Entity<DerivedEntity>());
修改强>
也许Types
配置足以达到您的目的。
modelBuilder.Types<BaseEntity>().Configure(entityTypeConfiguration => /* configure using entityTypeConfiguration */);
否则,如评论所述,您可能需要反思。例如,假设您的所有派生类与BaseEntity
类位于同一个程序集中,并且上面的ConfigureBaseEntity
方法位于类BaseEntityConfiguration
中。
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
var configurationMethod = typeof(BaseEntityConfiguration).GetMethod("ConfigureBaseEntity");
foreach (Type t in typeof(BaseEntity).Assembly.GetTypes().Where(x => x.IsSubclassOf(typeof(BaseEntity))))
{
var configurator = entityMethod.MakeGenericMethod(t).Invoke(modelBuilder, new object[0]);
configurationMethod.MakeGenericMethod(t).Invoke(null, new object[1] { configurator });
}
但是,如果是我的代码,我宁愿为每个实体类编写一行代码,而不是去动态发现。