Подтвердить что ты не робот

Как генерировать и автоматически увеличивать Id с Entity Framework

Пересмотренный весь пост.

Я пытаюсь отправить следующий запрос JSON POST через Fiddler:

{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:"1", Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

Почему Entity Framework не генерирует и не увеличивает количество идентификаторов? Мой класс 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; }
}

Вот метод контроллера. Когда в режиме отладки, и я отправляю запрос через Fiddler, он разрывается на db.SaveChanges(); и дает ошибку, увиденную чуть выше.

    // POST api/xxx/create
    [ActionName("create")]
    public HttpResponseMessage PostUser(User user)
    {
        if (ModelState.IsValid)
        {
            db.Users.Add(user);
            db.SaveChanges();

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, user);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = user.Id }));
            return response;
        }
        else
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }
    }

Что случилось?

Решение

Вместо этого замените строку Id на int и удалите аннотации данных. Переименовал идентификатор в UserId, все еще соблюдая правила, и внес изменения там, где это необходимо, в другой POCO, чтобы соответствовать изменениям.

4b9b3361

Ответ 1

Это предположение:)

Это потому, что идентификатор является строкой? Что произойдет, если вы измените его на int?

Я имею в виду:

 public int Id { get; set; }

Ответ 2

У вас плохой дизайн стола. Вы не можете автоинкремент строки, что не имеет никакого смысла. У вас есть в основном два варианта:

1.) изменить тип идентификатора на int вместо строки
2.) не рекомендуется!!! - обрабатывайте автоинкремент самостоятельно. Сначала вам нужно получить последнее значение из базы данных, проанализировать его до целого числа, увеличить его и снова привязать к объекту как строку. ОЧЕНЬ ПЛОХАЯ идея

Первая опция требует изменения каждой таблицы, содержащей ссылку на эту таблицу, но она того стоит.

Ответ 3

попробуйте отправить действительный json с цитируемыми строками:

{
    "Username": "test",
    "FirstName": "foo",
    "LastName": "bar",
    "Password": "123",
    "Headline": "Tuna"
}