我通过迭代从 EntityBase 继承的任何实体并将它们添加到我的 Context 来动态创建我的 DbContext:
private void AddEntities(DbModelBuilder modelBuilder)
{
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var entityTypes = assembly.GetTypes()
.Where(x => x.IsSubclassOf(typeof(EntityBase)) && !x.IsAbstract);
foreach (var type in entityTypes)
{
dynamic entityConfiguration = entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { });
EntityBase entity = (EntityBase)Activator.CreateInstance(type);
//Add any specific mappings that this class has defined
entity.OnModelCreating(entityConfiguration);
}
}
}
这样,我可以有许多命名空间,但在我的基本命名空间中只有一个通用存储库,它可以在任何地方使用。此外,在使用多个命名空间的应用程序中,基础存储库已经设置为使用所有加载的命名空间中的所有实体。我的问题是,我不想让 EntityFramework.dll 成为公司中每个命名空间的依赖项。所以我调用 OnModelCreating 并将 EntityTypeConfiguration 传递给该类,以便它可以添加任何映射。这很好用,下面是我如何添加一个映射来告诉模型我的“描述”属性来自一个名为“描述符”的列:
class Widget... {
public override void OnModelCreating(dynamic entity)
{
System.Linq.Expressions.Expression<Func<Widget, string>> tmp =
x => x.Description;
entity.Property(tmp).HasColumnName("Descriptor");
}
好消息是,我的实体类没有引用 EF,这个方法只调用一次,当上下文创建时,如果我们废弃 EF 并在将来去别的地方,我的类不会有各种属性特定于它们中的EF。
问题是,它超级难看。我如何让模型以比创建这些更简单的方式了解列映射和键Expressions
以获取要映射的属性,而无需在我的 poco 类中对 EF 进行硬编码引用?