当使用基类和私有setter时,关键组件“Id”不是“TypeName”类型的声明属性
我想为实体使用抽象基类,它不映射到任何表:
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 : EntityTypeConfiguration where TEntity : Entity { public EntityConfiguration() { HasKey(o => o.Id); Property(o => o.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } } public class OrderConfiguration : EntityConfiguration { 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 Orders { get; set; } }
现在,当我试图查询这样的订单时:
using (var context = new Context()) { foreach (var order in context.Orders) { Console.WriteLine(order.Customer); } }
我得到一个例外:
关键组件“Id”不是“订单”类型的声明属性。 validation它是否未从模型中明确排除,并且它是有效的原始属性。
我在SO上读了几个问题,发现我的方法看起来是正确的。 然后,我稍微修改了基类并使用公共 setter制作了Id
:
public abstract class Entity { public virtual int Id { get; set; } }
而且(这是一个奇迹!)示例代码工作正常。 此外,它没有基本Entity
类(当在Order
定义Id
时)与私有设置器一起正常工作。
逻辑告诉我,这是EF的错误行为。
但是,可能是,我错过了什么?
EF喜欢访问所有密钥。 尝试使用protected,以便程序集可以访问ID,但外部不能。 对于EF团队来说,这似乎是一个合理的问题。
请参阅相关postentity framework代码是否首先支持只读导航属性
在实体类中保护id的setter:
public abstract class Entity { public virtual int Id { get; protected set; } }
我试过这个。 它会起作用