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);
            }
        }
    }

そうすれば、多くの名前空間を持つことができますが、どこでも使用される基本名前空間には 1 つの汎用リポジトリしかありません。また、複数の名前空間を使用するアプリでは、ベース リポジトリは、読み込まれたすべての名前空間のすべてのエンティティを使用するように既にセットアップされています。私の問題は、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 への参照がないことです。このメソッドは、コンテキストが作成されたときに 1 回だけ呼び出され、EF を破棄して将来別のものに移動した場合、私のクラスにはあらゆる種類の属性がありません。それらのEFに固有です。

問題は、それが非常に醜いことです。Expressionspoco クラス全体で EF への参照をハードコーディングせずに、これらを作成してプロパティをマップするよりも簡単な方法で、モデルに列マッピングとキーについて知らせるにはどうすればよいですか?

4

1 に答える 1

1

独自の属性を定義し、これらを使用して 内の構成を制御できますOnModelCreating()。キーを作成するための1つのlinqクエリと2番目のクエリで、列マッピングに必要なすべての詳細を(リフレクションを使用して)取得できるはずです。

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 に答える