どのテーブルにもマップされていないエンティティの抽象基本クラスを使用したい:
public abstract class Entity
{
public virtual int Id { get; private set; }
}
自動インクリメントになるのでId
、このプロパティを外部から変更できるようにしたくありません。したがって、そのセッターはprivate
です。
エンティティ タイプの例を次に示します。
public class Order : Entity
{
public virtual string Customer { get; set; }
}
...構成タイプ:
public class EntityConfiguration<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : Entity
{
public EntityConfiguration()
{
HasKey(o => o.Id);
Property(o => o.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class OrderConfiguration : EntityConfiguration<Order>
{
public OrderConfiguration()
{
Property(o => o.Customer).HasColumnName("customer");
ToTable("Customers");
}
}
...そしてコンテキスト:
public class Context : DbContext
{
public Context()
: base()
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new OrderConfiguration());
}
public DbSet<Order> Orders { get; set; }
}
今、次のような注文を照会しようとすると:
using (var context = new Context())
{
foreach (var order in context.Orders)
{
Console.WriteLine(order.Customer);
}
}
私は例外を取得しています:
キー コンポーネント 'Id' はタイプ 'Order' で宣言されたプロパティではありません。モデルから明示的に除外されていないこと、および有効なプリミティブ プロパティであることを確認してください。
SO でいくつかの質問を読んだところ、私のアプローチが正しいように見えることがわかりました。次に、基本クラスを少し変更し、パブリックセッターで作成Id
しました。
public abstract class Entity
{
public virtual int Id { get; set; }
}
そして (これは奇跡です!) サンプル コードは正常に動作します。また、プライベートセッターを使用して、ベースEntity
クラスがなくても(Id
で定義されている場合)正常に動作します。Order
ロジックによると、これは EF のバグのある動作です。
しかし、多分、私は何かが欠けていますか?