Révisé article entier.
J'essaie de publier le JSON suivant POST via Fiddler:
{Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}
Cependant, je reçois cette erreur:
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
Cependant, si j'envoie manuellement un ID aléatoire avec la demande, tout va bien. Ainsi:
{Id:"1", Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}
Pourquoi Entity Framework ne génère-t-il pas et n'incrémente-t-il pas automatiquement les ID? Ma classe POCO est la suivante:
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; }
}
Voici la méthode du contrôleur. Lorsque je suis en mode débogage et que j'envoie la requête via Fiddler, il se rompt à db.SaveChanges();
et donne l'erreur vue un peu plus haut.
// 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'est-ce qui ne va pas?
Solution
Modifiez plutôt string id en int et supprimez les annotations de données. A renommé l'ID en UserId, toujours selon la convention, et a apporté des modifications si nécessaire dans d'autres POCO pour correspondre aux modifications.
C'est une conjecture :)
Est-ce parce que l'ID est une chaîne? Que se passe-t-il si vous le changez en int?
Je veux dire:
public int Id { get; set; }
Vous avez un mauvais design de table. Vous ne pouvez pas auto-incrémenter une chaîne, cela n'a aucun sens. Vous avez essentiellement deux options:
1.) changer le type d’ID en int
au lieu de chaîne
2.) Non recommandé !!! - gérer l'auto-incrémentation par vous-même. Vous devez d’abord extraire la dernière valeur de la base de données, l’analyser dans l’entier, l’incrémenter et la relier à l’entité sous forme de chaîne. TRES MAUVAISE idée
La première option nécessite de changer chaque table qui a une référence à cette table, MAIS ça vaut le coup.