【问题标题】:Cannot insert NULL into column while value is not null值不为空时无法将 NULL 插入列
【发布时间】:2017-08-26 16:42:30
【问题描述】:

所以我在尝试向实体添加实例时遇到了这个奇怪的问题。它是一个使用 EF 6.0 的 asp.net 应用程序。

例外:

SqlException:无法将值 NULL 插入到列“OrderId”中, 表'BETA.MDF.dbo.Orders';柱子 不允许空值。插入失败。声明已终止。

我的代码:

User user = (User)Session["CurrentUser"];
BetaEntities entities = new BetaEntities();

Beta.Order order = new Beta.Order();
order.OrderId = Guid.NewGuid().ToString();
order.OrderDate = DateTime.Now;
order.OrderedBy = user.UserId;
order.HandledBy = entities.Users.Where(x => x.Rank > 0).Select(i => i.UserId).FirstOrDefault();

entities.Orders.Add(order);

entities.SaveChanges();

我的桌子:

这也是我的订单类,我已经试过[Databasegenerated]

public partial class Order
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string OrderId { get; set; }
    public System.DateTime OrderDate { get; set; }
    public int OrderedBy { get; set; }
    public int HandledBy { get; set; }
}

示例条目:

如果您需要更多详细信息,请告诉我。

编辑:

我尝试将 OrderID 的数据库数据类型设置为 UNIQUEIDENTIEFIER 并更新了实体模型,因此数据库应该生成 guid(我删除了自己,但仍然遇到相同的异常。

这是我的新课:

public partial class Order
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public System.Guid OrderId { get; set; }
    public System.DateTime OrderDate { get; set; }
    public int OrderedBy { get; set; }
    public int HandledBy { get; set; }
}

编辑:

如果我将 OrderID 设为 NULLABALE 并删除主键,则会出现以下异常:

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException: '存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=472540。'

但这可以通过添加主键来解决:(因此删除 PK 并将其设置为 NULLABLE 不起作用。

我还需要自己分配 GUID 以供进一步使用,因此让数据库自己分配 guid(使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)])也不是一种选择。

【问题讨论】:

  • this 不确定,但它可能会帮助你,祝你好运
  • 您会收到非常清晰的异常消息:无法将值 NULL 插入到列“OrderId”中,因为列不允许空值。只需将列设置为允许NULL 值。
  • 字符串的标识没有用
  • 如果我设置为允许空值的列,那么它不能是主键,我想成为主键。
  • 那你为什么将NULL设置为标识列,目的是什么?

标签: c# sql asp.net entity-framework


【解决方案1】:

您的问题是您将DatabaseGenerated 属性设置为OrderId 列。

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string OrderId { get; set; }

使用此属性,EF 将忽略您设置为 OrderId 的值,并“尝试”生成唯一值,但生成唯一值不适用于 stringOrderId 将是 NULL,当 INSERT 查询时生成。

如果您使用 EF “代码优先”,则将 OrderId 的类型更改为 Guid 并从代码中删除下一行

order.OrderId = Guid.NewGuid().ToString();  

并保留DatabaseGenerated 属性不变。
当对列使用DatabaseGenerated 属性时 - 表示该列的值将由数据库生成。

更改Order 类的结构后,您需要相应地更新数据库。如果您使用“代码优先”方法,那么您需要生成迁移脚本并针对您的数据库运行它。在“数据库优先”的方法中,您需要手动更新数据库

即使您说删除 DatabaseGenerated 属性也无济于事,这将是 Ivan Stoev 在 cmets 中建议的最简单的解决方案。
因为您使用Guid.NewGuid().ToString() 自己生成唯一字符串。

【讨论】:

  • 如果我删除它,我仍然会得到同样的异常
  • 这个答案缺少两件事:将OrderId 的类型更改为Guid,是的。但还要调整数据库中的列类型以匹配,并给它一个默认约束newid()(或newsequentialid())。
  • 如果您删除它 - 如果数据库已相应更新,它应该可以工作。
  • @hvd,不确定但迁移脚本不会自动执行吗?
  • @Fabio 如果启用了迁移,我不知道。但是 OP 没有指定迁移,所以我不假设它们已启用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
相关资源
最近更新 更多