0

我通过迭代从 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 进行硬编码引用?

4

1 回答 1

1

您可以定义自己的属性并使用它们来控制OnModelCreating(). 您应该能够在一个 linq 查询和第二个查询中获得(使用反射)列映射所需的所有详细信息以创建键。

public class DatabaseNameAttribute : Attribute
{
    private readonly string _name;
    public DatabaseNameAttribute(string name)
    {
        _name = name;
    }
    public string Name
    {
        get
        {
            return _name;
        }
    }
}

public class KeySequenceAttribute : Attribute
{
    private readonly int _sequence;
    public KeySequenceAttribute(int sequence)
    {
        _sequence = sequence;
    }
    public int Sequence
    {
        get
        {
            return _sequence;
        }
    }
}

[DatabaseName("BlogEntry")]
public class Post
{
    [DatabaseName("BlogId")]
    [KeySequence(1)]
    public int id { get; set; }
    [DatabaseName("Description")]
    public string text { get; set; }
}
于 2013-02-12T20:34:33.213 回答