1

それぞれが対応する同一のテーブルにマップされているクラス名を除いて、同一のエンティティがいくつかあります。各テーブルのマッピングは次のようになります。

modelBuilder.Entity<Foo>().Map(x =>
{
  x.MapInheritedProperties();
  x.ToTable("Foo");
})

このアプローチは機能しますが、繰り返します。

再配置を取り除くことを期待してこのクラスを作成しました。ここでは簡潔にするために簡略化しています。

public class Generic<T>
{
    public Generic(DbModelBuilder modelBuilder, string tableName)
    {
        modelBuilder.Entity<T>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable(tableName);
        });
    }
}

理解できない次のコンパイラエラーが発生します。

The type 'T' must be a reference type in order to use it as parameter 'TEntityType' in the generic type or method 'System.Data.Entity.DbModelBuilder.Entity<TEntityType>()'
  • 多くの.Netコーダーと同様に、私はジェネリックスをよく使用しますが、頻繁には記述しません。
  • 私はしばらくの間EFを使用していますが、CodeFirstはかなり初めてです。
  • 私は運が悪かったので、SOの内外で多くの検索を行いました。
  • 私は何が間違っているのですか?何がわからないの?

よろしくお願いします、ジム

4

3 に答える 3

4

ジェネリック パラメータの制約を追加するだけwhere T : classです。

public class Generic<T>
   where T : class
{
    public Generic(DbModelBuilder modelBuilder, string tableName)
    {
        modelBuilder.Entity<T>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable(tableName);
        });
    }
}

メソッドに同じ制約が存在するDbModelBuilder.Entity<T>ため、ジェネリック クラスに同じ制約が必要です。

于 2013-03-21T21:43:58.727 に答える
3

エラーは、ジェネリックにclass制約がないことを示しています。「型パラメータの制約」については、こちらをお読みください。

したがってGeneric<T>、次のように宣言する必要があります

public class Generic<T> where T: class
{
    public Generic(DbModelBuilder modelBuilder, string tableName)
    {
        modelBuilder.Entity<T>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable(tableName);
        });
    }
}

ただし、EntityTypeConfigurationを使用することをお勧めします。このクラスを使用すると、エンティティマッピングをコンテキストから分離し、必要な種類の継承を実装できます。

例えば:

public abstract class EntityConfiguration<T> : EntityTypeConfiguration<T>
    where T : Entity
{
    protected EntityConfiguration()
    {
        ToTable(typeof(T).Name);

        // All primary keys are named as <EntityName>Id
        Property(e => e.Id)
            .HasColumnName(typeof(T).Name + "Id");
    }
}

このクラスは、すべてのエンティティがタイプの名前と同じ名前のテーブルへのマッピングを持ち、すべてのテーブルに名前が付いた主キー列があることを示します<TableName>Id

次に、エンティティのマッピング構成をFoo次のように宣言できます。

public class FooConfiguration : EntityConfiguration<Foo>
{
    public FooConfiguration()
    {
        Map(m => m.MapInheritedProperties());
        // add you mapping logic here
    }
}

次に、構成をDbContextに登録する必要があります。

public class MyDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooConfiguration());
    }
}
于 2013-03-21T21:48:01.307 に答える
0

EF は、これを可能にするクラスを提供します。

class SomeEntityMapping : EntityTypeConfiguration<SomeEntity>
{
    public SomeEntityMapping()
    {
        ToTable("My_Entity");
        HasKey(e => e.Id);
        //...
    }
} 

次に、DbContext で OnModelCreating をオーバーライドし、マッピングを構成に追加します。

protected override void OnModelCreating(DbModelBuilder builder)
{
   builder.Configurations.Add(new MyEntityConfiguration());
}
于 2013-03-21T21:49:01.447 に答える