Pregunta Cómo generar e incrementar automáticamente Id con Entity Framework


Revisado publicación completa.

Estoy intentando publicar la siguiente solicitud JSON POST a través de Fiddler:

{Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

Sin embargo, estoy recibiendo este error:

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

Aunque si envío manualmente un ID aleatorio junto con la solicitud, entonces todo está bien. Al igual que:

{Id:"1", Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

¿Por qué Entity Framework no genera e incrementa automáticamente el Id? Mi clase POCO es la siguiente:

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; }
}

Aquí está el método del controlador. Cuando estoy en modo de depuración y envío la solicitud a través de Fiddler, se rompe en db.SaveChanges(); y da el error visto un poco más arriba.

    // 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);
        }
    }

¿Qué pasa?

Solución

Cambie la Id. De cadena a int en su lugar y elimine las anotaciones de datos. Se cambió el nombre de Id a UserId, aún se sigue la convención, y se realizaron cambios cuando fue necesario en otros POCO para coincidir con los cambios.


32
2018-04-18 09:27


origen


Respuestas:


Esto es una suposición :)

¿Es porque la identificación es una cadena? ¿Qué pasa si lo cambias a int?

Quiero decir:

 public int Id { get; set; }

34
2018-04-18 12:41



Tienes un mal diseño de mesa. No puede autoincrementar una cadena, eso no tiene ningún sentido. Tienes básicamente dos opciones:

1.) cambiar el tipo de ID a int en lugar de cadena
2.) no recomendado !!! - Maneje autoincrement usted mismo. Primero necesita obtener el último valor de la base de datos, analizarlo en el entero, incrementarlo y adjuntarlo a la entidad como una cadena nuevamente. MUY MALA idea

La primera opción requiere cambiar cada tabla que tenga una referencia a esta tabla, PERO vale la pena.


7
2018-04-18 12:57



intente publicar un JSON válido con cadenas entre comillas:

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

-3
2018-04-18 10:47