如何告知实体(代码优先)不将密钥ID字段发送到数据库?

时间:2013-12-19 02:26:22

标签: entity-framework ef-code-first code-first

我的代码:

Models.Resource r = new Models.Resource();
r.Name = txtName.Text;
r.ResourceType = resTypes.Find(rt => rt.Name == "Content");

r.ResourceContents.Add(_resourceContent.Find(rc => rc.ID == _resourceContentID));

ctx.Resource.Add(r);
ctx.SaveChanges();

ctx.SaveChanges()导致错误: 当IDENTITY_INSERT设置为OFF时,无法在表'Resources'中为identity列插入显式值。

查看发送给SQL的内容:     ADO.NET:Execute NonQuery“INSERT [dbo]。[Resources]([ID],[Name],[Description],[IsOnFile],          [ContentOwnerAlias],[ContentOwnerGroup],[ResourceTypes_ID])     VALUES(@ 0,@ 1,@ 2,@ 3,@ 4,@ 5,NULL)“

我的POCO资源将ID作为密钥:

public partial class Resource
{
  public Resource()
  {
  }

  [Key]
  public int ID { get; set; }

我的地图代码:

public class ResourceMap : EntityTypeConfiguration<Resource>
{
  public ResourceMap()
  {
    // Primary Key
    this.HasKey(t => t.ID);

如何告诉Entity不将密钥ID字段发送到数据库?

2 个答案:

答案 0 :(得分:1)

如果您的PK是由数据库生成的(如identity),则必须在地图中对其进行配置。

public class ResourceMap : EntityTypeConfiguration<Resource>
{
   public ResourceMap()
   {
        // Primary Key
        this.HasKey(t => t.ID);
        this.Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
   }
}

答案 1 :(得分:1)

您不需要HasKey(t => t.ID) Fluent API映射或[Key]数据属性,因为按照惯例,EF将假定名为ID的整数字段是密钥并且是数据库生成的。

顺便说一句,我建议当你不遵守惯例时,你应该选择一种方法或另一种方法 - 否则你会重复自己,当你想要改变一些东西时,你需要在两个地方改变它。

我不确定为什么数据库中的字段尚未生成数据库 - 也许当您通过流畅的api定义字段时,您也必须指定该字段。我所知道的是,为了使EF 更改成为数据库生成的关键字段,您需要删除该表。

所以 - 回滚迁移或删除表/数据库,然后删除数据属性,删除流畅的映射并重新创建。

此问题目前正在实体框架中的“积压”。如果您想投票,可以在此处执行此操作:Migrations: does not detect changes to DatabaseGeneratedOption

其他参考文献:

Identity problem in EF

Switching Identity On/Off With A Custom Migration Operation