I want to use an abstract base class for entities, which is not mapped on any table:
public abstract class Entity
{
public virtual int Id { get; private set; }
}
Since Id
will be auto-increment, I don't want to allow to change this property from outside. Hence, its setter is private
.
Here's a sample entity 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'm trying to query orders like this:
using (var context = new Context())
{
foreach (var order in context.Orders)
{
Console.WriteLine(order.Customer);
}
}
I'm getting an exception:
The key component 'Id' is not a declared property on type 'Order'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.
I've read several questions at SO, and found, that my approach looks correct. Then, I've modified base class a little and made Id
with public setter:
public abstract class Entity
{
public virtual int Id { get; set; }
}
And (it's a miracle!) the sample code works fine. Also, it works fine without base Entity
class (when Id
is defined in Order
) with private setter.
Logic tells me, that is a buggy behavior of EF.
But, may be, I'm missing something?
EF likes to access all keys. Try using protected so the assembly can access the ID but externals cant. Seems like a reasonable question for the EF team to me.
See related post Does the Entity Framework code first support readonly navigation property
make setter of id in entity class protected :
public abstract class Entity
{
public virtual int Id { get; protected set; }
}
i tried this . it will be work
来源:https://stackoverflow.com/questions/14080521/the-key-component-id-is-not-a-declared-property-on-type-typename-when-using