C# 如何使用实体框架生成和自动增加Id

C# 如何使用实体框架生成和自动增加Id,c#,json,entity-framework,asp.net-web-api,C#,Json,Entity Framework,Asp.net Web Api,修订了整个职位 我正试图通过Fiddler发布以下JSON post请求: {Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"} 但是我得到了这个错误: Message "Cannot insert the value NULL into column 'Id', table 'xxx_f8dc97e46f8b49c2b825439607e89b59.dbo.User'; colum

修订了整个职位

我正试图通过Fiddler发布以下JSON post请求:

{Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}
但是我得到了这个错误:

Message "Cannot insert the value NULL into column 'Id', table 'xxx_f8dc97e46f8b49c2b825439607e89b59.dbo.User'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated." string
虽然如果我在请求时手动发送一个随机Id,那么一切都很好。像这样:

{Id:"1", Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}
为什么实体框架不生成并自动增加Id?我的POCO课程如下:

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string Headline { get; set; }
    public virtual ICollection<Connection> Connections { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Phonenumber> Phonenumbers { get; set; }
    public virtual ICollection<Email> Emails { get; set; }
    public virtual ICollection<Position> Positions { get; set; }
}

public class Connection
{
    public string ConnectionId { get; set; }
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

public class Phonenumber
{
    public string Id { get; set; }
    public string Number { get; set; }
    public int Cycle { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}
怎么了

解决方案

将字符串Id改为int并删除数据批注。将Id重命名为UserId,仍然遵循惯例,并在其他POCO中进行必要的更改以匹配更改。

这是一个猜测:)

是因为ID是字符串吗?如果将其更改为int,会发生什么

我的意思是:

 public int Id { get; set; }

你的桌子设计不好。不能自动递增字符串,这没有任何意义。您基本上有两种选择:

1.)将ID的类型更改为
int
而不是字符串
2.)不推荐!!!-自己处理自动递增。您首先需要从数据库中获取最新的值,将其解析为整数,并将其递增,然后再次将其作为字符串附加到实体。好主意


第一个选项要求更改每个引用此表的表,但这是值得的。

当您调试控制器时,一步一步地,在db.SaveChanges()处是否会出现错误?可能是实体验证错误?你完全正确,这是我的糟糕设计。谢谢你的意见:)回复:不推荐!!!-我不同意这一点。db完成的自动增量意味着您必须点击db来创建一个并不总是很好的记录。但这是另一个话题…@Tymek,呃,无论哪种方式,你都必须点击数据库来确定下一个Id。但是,如果让数据库为您处理,只需将其他参数传递给db,db就会在处理插入过程中为您计算出值。如果您自己处理自动递增,则必须先从数据库获取最新的id,然后才能实际发送查询以插入记录。那是去db的一次额外旅行!不提数据库一次被多个应用程序/用户访问的情况,这真是一个需要解决的噩梦。@Tymek,我真的看不出这是一个好主意。@Tymek,是的,Id可以是任何东西,但是如果你不先点击数据库检查,你怎么知道哪个Id不被使用??它必须是独一无二的,所以你需要有一个机制来处理这个问题。情况越复杂,实现它的难度就越大,尤其是在并发场景中(如ASP.NET,这个问题是关于什么的),您需要为同时访问数据库的所有用户处理这个问题。如果您创建了一个Id,该怎么办?您将其传递到数据库,并得到一个错误。你会告诉用户什么?“哎呀,我们生成了一个错误的Id,让我们再试一次”?我觉得很傻,但现在我很清楚它应该是
int
。只是当我开始的时候,一切都是一个字符串,我有点忘记了。谢谢;)另一个提示是不要忘记字段/DB列需要在模型中表示为属性,而不仅仅是普通字段/成员。
 public int Id { get; set; }