I want to use an abstract base class for entities that does not appear in any table:
public abstract class Entity { public virtual int Id { get; private set; } }
Since Id will automatically increase, I do not want to allow this property to be changed externally. Therefore, its setter is private .
Here is an example of an object type:
public class Order : Entity { public virtual string Customer { get; set; } }
... configuration types:
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"); } }
... and context:
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; } }
Now when I try to request such orders:
using (var context = new Context()) { foreach (var order in context.Orders) { Console.WriteLine(order.Customer); } }
I get an exception:
The key component "Identifier" is not a declared property in the type "Order". Make sure that it has not been explicitly excluded from the model and that it is a valid primitive property.
I read a few questions in SO and found that my approach looks right. Then I changed the base class a bit and made Id with an open setter:
public abstract class Entity { public virtual int Id { get; set; } }
And (this is a miracle!) The sample code works fine. Also, it works fine without the Entity base class (when Id is defined in Order ) using a private setter.
Logic tells me that this is the wrong behavior of EF.
But maybe I'm missing something?