c# - EF : Map base class property with fluent API

标签 c# entity-framework

我首先遇到继承代码问题。 我的基类如下所示:

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 的附加列。所以我尝试像这样使用 Fluent 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'。” 如何避免定义键并仅更改属性映射?我在派生类中有键。

最佳答案

您可以将基类配置包装在通用方法中,并为每个具体实体类型调用它。

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  */);

否则,正如评论所述,您可能需要反射(reflection)。例如,假设所有派生类都与 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 });
}

但是,如果是我的代码,我宁愿为每个实体类编写一行代码,而不是进行动态发现。

关于c# - EF : Map base class property with fluent API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41806632/

相关文章:

c# - 首先在 Entity Framework 代码中查询自定义类型

c# - 使用 Dynamic Linq 处理动态选择

c# - 为什么 DateTime 没有内置类型?

c# - TimeSpan.TryParseExact 不工作

c# - 如何从 Razor、MVC 渲染 # Symbol

asp.net-mvc - ASP.NET MVC 5 - 多对一关系的脚手架

c# - 具有多对多关系的linq查询

c# - 来自不同上下文的实体是否相互兼容?

c# - 在 Windows 窗体控件中调整大小以及调整窗体大小

c# - 使用 EF 处理嵌套表