首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何自动增加Id以外的密钥

如何自动增加Id以外的密钥
EN

Stack Overflow用户
提问于 2014-08-26 19:38:57
回答 2查看 86关注 0票数 0

我首先使用EF代码,并有一个没有名为Id的键的表。对于这个表,命名键SelectorId是有意义的。问题是,当我添加一个新行时,我会得到一个错误:

无法将值NULL插入“SelectorId”列、表“dbProgramData.dbo.electors”;列不允许空值。插入失败。声明已被终止。

当然,它不允许空-它是这个表的主键,但是我假设这个键是自动递增的。我有这样定义的模型:

代码语言:javascript
复制
public class Selector
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SelectorId { get; set; }

    public string ProgramId { get; set; }

    ....

}

我试图在此代码中添加一行代码(在本地PC上使用VS可以很好地工作,但在发布后远程VPS上出现上述错误时会失败:

代码语言:javascript
复制
ProgramDbContext dbProgramData = new ProgramDbContext();

Selector selector = new Selector();

selector.ProgramId = programId;

dbProgramData.Selectors.Add(selector)
dbProgramData.SaveChanges();

在ProgramDbContext类中,我有:

代码语言:javascript
复制
public DbSet<Selector> Selectors { get; set; }

我怀疑如果我将SelectorId重命名为Id,这个问题就解决了吗?运行Add迁移后,上/下脚本显示:

代码语言:javascript
复制
CreateTable(
    "dbo.Selectors",
    c => new
        {
            SelectorId = c.Int(nullable: false, identity: true),
            ProgramId = c.String(),

    ....

有人能告诉我我做错了什么吗?我所创建的两个表也有同样的问题,它们都有一个名为Id以外的Pk。

更新

正如建议的那样,我进入了远程服务器上这个表的SSMS和Design。我看到Is Identity被设置为No。我双倍地检查了我的本地数据库表,并将Is Identity设置为“是”。

我将数据库表发送到远程VPS服务器的方式是通过右键单击数据库,然后在任务->导入数据上使用SSMS。我指向本地.\SQLEXPRESS并执行导入。看来进口是成功的,但显然不是。在执行导入之前,我将删除远程数据库中的所有表。

这个方法不应该在导入数据的同时创建精确的模式吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-26 23:42:13

要说清楚:

  • EF使用独立于物理数据库(实体数据模型,也称为EDM)的模式的定义。
  • 数据库有自己的模式,独立于EDM。

要使事情正常工作,这两个模式必须是一致的。因此,如果数据库中有标识列,则必须在EDM中正确定义该列。如前所述,EDM列必须具有DatabaseGenerated属性等于DatabaseGeneratedOption.Identity。

在您的开发机器中,我不知道您是使用database,还是Code,还是绘制一个EDM模式来生成数据库,但是很明显,这个模式与数据库是一致的,所以它工作得很好。

如果您尝试使用一个EDM架构,它不会对数据库产生太大影响,您就会得到错误。

身份列是这样工作的:

  • 在Server中,当将identity属性添加到表的列时,当您插入新行时,无法指定该列的值: SQL服务器将自动生成顺序编号,并插入该行。
  • 如果EDM的列标记为DatabaseGenerated,则当您使用它插入新行时,生成的SQL:
    • 在insert语句中不包括列
    • 插入之后,它选择scope_identity()函数来获取服务器生成的值。

因此,正常情况下,如果电火花和数据库没有一致的信息,插入就会失败。

在这种情况下,问题显然是一个部署问题。你可以尝试其他方法来做到这一点:

  • 在开发机器中备份数据库,并在VPS SQL Server中还原数据库
  • 使用SSMS查找数据库的文件(查看DB属性)。一旦您知道文件在哪里,请分离DB (在SSMS中,右键单击数据库,您将在“任务”菜单选项下找到此选项)。分离VPS中的DB (如果存在的话)。现在,您可以将文件从开发机器复制到服务器,并将其再次附加到dev机器和服务器中。

这两种方法是完全安全的。如果使用导入/导出或任何其他操作复制DB,则可能会遇到麻烦,因为有一些选项需要配置。

顺便说一句,如果您首先使用EF代码,除非您使用属性对其进行修改,否则默认情况下,任何整数类型的IdTableNameId都被视为DatabaseGenerated列。(这是按约定配置的)。但是,如果不遵循约定,则始终可以使用属性(或Fluent API)配置列,将其标记为Key,并指定生成该列的位置。

票数 1
EN

Stack Overflow用户

发布于 2014-08-26 19:43:01

在sql server中,goto设计表的视图。单击要递增的列,在“列属性”面板中,向下滚动到“标识规范”。将其设置为“是”,然后可以将其设置为“自动增量1”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25513913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档