Come generare e incrementare automaticamente Id con Entity Framework

Revisione dell’intero post.

Sto cercando di pubblicare la seguente richiesta POST JSON tramite Fiddler:

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

Tuttavia sto ricevendo questo errore:

 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 

Anche se invio manualmente un ID casuale insieme alla richiesta, tutto va bene. Così:

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

Perché Entity Framework non genera e incrementa automaticamente gli ID? La mia class POCO è la seguente:

 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 Connections { get; set; } public virtual ICollection
Addresses { get; set; } public virtual ICollection Phonenumbers { get; set; } public virtual ICollection Emails { get; set; } public virtual ICollection 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; } }

Ecco il metodo del controller. Quando in modalità di debug e invio la richiesta tramite Fiddler, si interrompe a db.SaveChanges(); e dà l’errore visto un po ‘sopra.

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

Cosa c’è che non va?

Soluzione

Cambia invece ID stringa int e rimuovi annotazioni dati. Rinominato l’Id in UserId, sempre seguendo la convenzione, e apportato le modifiche, se necessario, in altri POCO per corrispondere alle modifiche.

Questa è una supposizione 🙂

È perché l’ID è una stringa? Cosa succede se lo cambi in int?

Intendo:

  public int Id { get; set; } 

Hai un cattivo design da tavolo. Non è ansible eseguire l’autoincremento di una stringa, il che non ha alcun senso. Hai fondamentalmente due opzioni:

1.) cambia il tipo di ID in int anziché in string
2.) non raccomandato !!! – Gestisci l’autoincremento da solo. È prima necessario ottenere l’ultimo valore dal database, analizzarlo all’intero, incrementarlo e collegarlo nuovamente all’ quadro come una stringa. Idea MOLTO CATTIVA

La prima opzione richiede di cambiare ogni tabella che ha un riferimento a questa tabella, ma ne vale la pena.

prova a postare un json valido con le stringhe tra virgolette:

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