【问题标题】:Cannot insert the value NULL into column 'CompanyId' column does not allow nulls. INSERT fails无法将值 NULL 插入列“CompanyId”列不允许空值。插入失败
【发布时间】:2016-12-21 14:16:18
【问题描述】:

当我尝试使用 EF 保存到我的数据库时出现此错误。

无法将值 NULL 插入到列“CompanyId”中,列不允许空值。

从消息中很明显问题出在哪里,但在我的代码中没有看到任何原因。

这是我的模型:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public string CompanyCountry { get; set; }
public string CompanyCity { get; set; }
public string CompanyPostalCode { get; set; }
public string CompanyPhoneNumber { get; set; }
public string EmailCA { get; set; }

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "CompanyId,CompanyName,CompanyAddress,CompanyCountry,CompanyCity,CompanyPostalCode,CompanyPhoneNumber,EmailCA")] Company company)
{
    if (ModelState.IsValid)
    {
        db.Companies.Add(company);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(company);
}

我对这些属性的期望是从它们那里获得一个自动生成的密钥,但显然这不起作用。

有人可以帮忙解释一下吗?

【问题讨论】:

  • 显示你的数据库CompanyId是否是not null
  • @Ganesh_Devlekar 错误消息已经显示它在数据库中是not null,这正是它应该是的。但是,如果数据库定义使其不可为空,但不会使其成为标识列,则可能会出现问题。所以查看表/列的数据库定义还是很有用的。
  • 向我们展示足以诊断问题的代码。
  • 我刚刚编辑了问题。
  • 唯一的解释是数据库列没有设置为Identity。

标签: asp.net-mvc entity-framework


【解决方案1】:

基于您的代码的唯一解释是 CompanyId 的数据库列定义未设置为 Identity。当您从 DbContext 执行插入时,将不会提供 CompanyId 的值,因为它假定数据库将根据您在 CompanyId 属性上提供的属性 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 生成它。 (错误的)架构具有 CompanyId 的不可为空(且无标识)列,因此例外。

【讨论】:

  • 如果“未设置做 indetity 你的意思是”是身份 - 假。好的。这是我双击列时看到的
  • @RobertRoss - 对,您当前的(错误的)数据库架构将该列标记(未标记)为身份。如果您更改数据库架构并将 CompanyId 选中(标记)为 Identity,您将解决问题。
  • 有什么建议吗?
  • @RobertRoss - 如果您使用 SQL,请查看 stackoverflow.com/q/1049210/1260204 或者您可以使用设计器并以这种方式保存更改。
【解决方案2】:

如果您先做数据库或先做模型,请检查您的 .edmx 并查看 CompanyId 的属性中的 StoreGeneratedPattern 是否设置为 IdentityComputedNone。如果此处设置不正确,请将其更改为Identity

如果您先编写代码,则 DB 列未设置为标识。

【讨论】:

  • 感谢您的回答。可能这确实是问题所在,但我什至不知道该文件在哪里。你能帮忙吗?
  • @RobertRoss - 如果您首先使用 EF 代码(并且基于您的模型属性),则不会有 .edmx 文件。
  • @RobertRoss 既然你要先写代码,你确实应该参考 Igor 的答案。
【解决方案3】:

您可以使用存储过程来产生一个身份(下一个 id),我使用了这样的一个:

ALTER procedure [dbo].[ctgetNextID]  @tableName nchar(40), @outid int output
AS      
    declare @id_next int      
    declare @id_table int
    select  @id_next = 0
    declare @id_inc int
    declare @sql nvarchar(200)

BEGIN TRANSACTION T1
    select @id_table = bord_tableid from custom_tables where bord_caption = @tableName

    exec('DECLARE my_cursor CURSOR FOR SELECT Id_NextId FROM ' +      
            'SQL_Identity WITH (UPDLOCK) WHERE Id_TableId ='+@id_table)      

    --open cursor and fetch max back      
    open my_cursor      
    fetch next from my_cursor into @id_next

    if (@@fetch_status=0) begin             
        select @id_inc = @id_next+1
        select @sql = 'update SQL_Identity set Id_NextId='+STR(@id_inc)+' where Id_TableId='+STR(@id_table)
            exec(@sql)      
        end 

        close my_cursor      
        deallocate my_cursor      
COMMIT TRANSACTION T1

       select @outid = @id_next
       return @outid



SET QUOTED_IDENTIFIER ON

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多