我正在使用EF Code First,并且有一个没有名为Id
的密钥的表。对于此表,命名Key SelectorId
是有意义的。问题是,当我添加新行时,我收到错误:
无法将值NULL插入“SelectorId”列表中 'dbProgramData.dbo.Selectors';列不允许空值。 INSERT失败。声明已经终止。
当然它不允许空值 - 它是该表的主键,但我假设Key是自动增量。我的模型定义如下:
public class Selector
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SelectorId { get; set; }
public string ProgramId { get; set; }
....
}
我正在尝试使用此代码添加一行(在我的本地PC上使用VS工作正常,但在发布后在远程VPS上出现上述错误失败:
ProgramDbContext dbProgramData = new ProgramDbContext();
Selector selector = new Selector();
selector.ProgramId = programId;
dbProgramData.Selectors.Add(selector)
dbProgramData.SaveChanges();
在ProgramDbContext类中,我有:
public DbSet<Selector> Selectors { get; set; }
如果我要将SelectorId
重命名为Id
,我怀疑此问题已得到解决?运行“添加迁移”后,向上/向下脚本显示:
CreateTable(
"dbo.Selectors",
c => new
{
SelectorId = c.Int(nullable: false, identity: true),
ProgramId = c.String(),
....
谁能告诉我我做错了什么?我在创建的两个表中遇到了同样的问题,并且它们都有一个名为Id
以外的Pk。
更新
正如所建议的那样,我在远程服务器上进入了该表的SSMS和Design View。我看到Is Identity
设置为否。我仔细检查了我的本地数据库表,Is Identity
设置为是,因为它应该是。
通过右键单击数据库,然后在Tasks - &gt;上,我将数据库表提供给远程VPS服务器的方式是使用SSMS。导入数据。我指向我的本地。\ SQLEXPRESS并执行导入。似乎导入成功,但显然不是。在执行导入之前,我将删除远程数据库中的所有表。
此方法不应该创建精确的模式以及导入数据吗?
答案 0 :(得分:1)
说清楚:
要使事情顺利进行,两个模式必须一致。因此,如果数据库中有标识列,则必须在EDM中正确定义该列。正如您所说,EDM列必须具有DatabaseGenerated属性等于DatabaseGeneratedOption.Identity。
在您的开发机器中,我不知道您是使用数据库优先或代码优先,还是绘制EDM架构来生成数据库,但很清楚架构是否一致与数据库,所以它工作正常。
如果您尝试使用的EDM示意图并不是数据库,那么您将会遇到错误。
这是标识列的工作方式:
scope_identity()
函数以获取服务器生成的值。因此,如果EDM和Databasedoesn具有一致的信息,则插入失败,这是正常的。
在这种情况下,问题显然是部署问题。您可以尝试其他方法:
这两种方法完全是故障安全的。如果您使用导入/导出或任何其他操作来复制数据库,则可能会遇到麻烦,因为有一些选项需要配置。
顺便说一下,如果您使用的是EF Code First,除非您使用属性对其进行修改,否则默认情况下,任何整数类型的Id
或TableNameId
都会被视为{{1列。 (按惯例,这是配置)。但是,如果您不遵循惯例,则始终可以使用属性(或Fluent API)配置列,将其标记为DatabaseGenerated
并指定其生成位置。
答案 1 :(得分:0)
在sql server中,转到有问题的表的设计视图。单击要增加的列,然后在列属性面板中,向下滚动到“标识规范”。将其设置为yes,然后您应该能够将其设置为自动递增1。