如何在实体框架中使用String属性作为主键

时间:2015-10-07 03:53:30

标签: c# sql database entity-framework entity-framework-6

我是EF的新手,尝试在ETF6.0中通过代码优先方法完成我的第一步,现在我遇到了问题。

我有一个属性

.state('posts', {
      url: '/posts/{id}',
      templateUrl: 'posts.html',
      controller: 'postsController as postsCtrl',
      resolve: {
        post: function('postsService', '$stateParams') {
           return postsService.getSinglePost($stateParams.id);
      }
    })

angular.module('flapperNews')
.controller('postsController', function($scope, post){
    $scope.post = post;
   console.log($scope.post); //undefined here
});

这是我的模型的主键。

但如果我运行

  

PM>更新数据库

程序包管理器控制台中的

命令用于更新对数据库的挂起迁移我收到以下错误:

  

标识栏' FooId'必须是数据类型int,bigint,smallint,   tinyint,或小数或数字,标度为0,并约束为   是不可侵犯的。

如果我将模型中的PK更改为

[Key]
public string FooId { get; set; }

一切正常。

但我需要PK为类型字符串,因为它在我的情况下绝对敏感。我知道有缺点,但对我来说这是必要的。

我在这里看到了一篇较旧的帖子How to make string as primary key in entity framework!

但似乎没有解决我的问题,或者我只是不理解它。

我真的不能在SQL数据库中使用字符串作为PK吗?

或者有办法做到这一点吗?

4 个答案:

答案 0 :(得分:38)

这是在没有启用Identity Autoincrement的情况下创建PK的正确方法:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string FooId { get; set; }

答案 1 :(得分:2)

如果您需要将主键作为字符串,请不要将其设为标识列。标识列将为您生成主键值,如果您打算自己生成值,则应关闭该值。

答案 2 :(得分:1)

将字符串作为主键的原因是什么?

我只是将主键设置为自动递增整数字段,并在字符串字段上放置一个索引。

这样,如果你在桌面上进行搜索,它们应该相对较快,并且所有连接和正常查找都不会受到速度的影响。

您还可以控制索引的字符串字段的数量。换句话说,如果您认为这样就足够了,您可以说“仅索引前5个字符”。或者,如果您的数据可能相对相似,则可以索引整个字段。

答案 3 :(得分:0)

对于其他不想更改其实体的人,另一个可能的答案是告诉 DbContext

  builder.Entity<Food>(b =>
  {
       b.Property(u => u.FooId).HasDefaultValueSql("newsequentialid()");
  });

这将告诉 DbContext Food 模型具有一个名为 FoodId 的ID,并且需要生成ID。

EF Core默认值:MSDN