2016-02-21 1 views
1

J'essaie d'insérer un utilisateur dans une table de conversation. Une conversation a une collection définie d'utilisateurs en tant que variable membre. C'est cette variable qui me trouble. Lorsque je tente de Poster une conversation Je reçois l'erreur:Problème de clé en double dans l'API Web

"ExceptionMessage": "Violation of PRIMARY KEY constraint 'PK_dbo.Users'. 
Cannot insert duplicate key in object 'dbo.Users'. 
The duplicate key value is([email protected]).\r\nThe statement has been terminated.", 

Je suis en train d'insérer un utilisateur existant dans une conversation mais il semble que il tente d'insérer un nouvel utilisateur qui est à l'origine d'une erreur en double.

classe Conversation:

[DataContract] 
public class Conversation 
{ 
    [Key] 
    [DataMember] 
    public string Key { get; set; } 
    [DataMember] 
    public string ConversationName { get; set; } 
    [DataMember] 
    public string Administrator { get; set; } 
    [DataMember] 
    public List<User> Members { get; set; } 

    public Conversation(string key, string name, string admin, List<User> members) 
    { 
     Key = key; 
     ConversationName = name; 
     Administrator = admin; 
     Members = members; 
    } 
} 

L'utilisateur est défini comme:

public class User 
{ 
    [Key] 
    [DataMember] 
    public String Email { get; set; } 

    [DataMember] 
    public String Password { get; set; } 

    [DataMember] 
    public Boolean Admin { get; set; } 
} 

Mon contrôleur est défini comme:

POST:

[HttpPost] 
public async Task<IHttpActionResult> PostConversation(Conversation convo) 
{ 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 
    db.Conversations.Add(convo); 
    await db.SaveChangesAsync(); 

    return CreatedAtRoute("DefaultApi", new { name = convo.Key }, convo); 
} 

GET:

[HttpGet] 
public async Task<IHttpActionResult> GetConversation(String key) 
{ 
    Conversation convo = await db.Conversations.FindAsync(key); 
    if (convo == null) 
    { 
     return NotFound(); 
    } 
    return Ok(convo); 
} 

Toute contribution serait appréciée! :)

EDIT Je ne l'exception inclus outter:

"ExceptionMessage": "An error occurred while saving entities that do not expose foreign key properties for their relationships. 
The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. 
Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. 
See the InnerException for details.", 

Répondre

1

Le problème est que ...

db.Conversations.Add(convo); 

... marque récursive toutes les entités qui appartiennent à convo comme Added. Donc, il essaye d'insérer de nouveaux enregistrements User au lieu de simplement définir la clé étrangère à ceux existants.

La solution est de fixer les User s au contexte avant d'ajouter la conversation:

foreach(var user in convo.Members) 
{ 
    db.Entry(user).State = System.Data.Entity.EntityState.Unchanged; 
} 
db.Conversations.Add(convo); 
+0

qui semble avoir résolu cette erreur que je ne reçois pas la même exception ... Merci beaucoup! Cependant je ne peux pas être sûr car j'ai encore, encore une fois, couru dans une autre erreur qui peut, encore, justifier à une question de son propre! '' ExceptionMessage ":" Impossible de convertir l'objet de type 'System.Collections.Generic.List'1 [AcademicAssistant.Models.User]' en type 'AcademicAssistant.Models.User'. ",' Ceci doit être en raison de la façon dont il est stocké dans la base de données mais je ne comprends pas le problème ou comment le résoudre.Dois-je poster une nouvelle question? – semiColon

+0

[link] (http://stackoverflow.com/questions/35543433/invalidcaseexception-when-using-entity-framwork) – semiColon

+0

Peut-être pourriez-vous jeter un oeil à une autre question d'esprit similaire, s'il vous plaît? [Ici c'est] (http://stackoverflow.com/questions/35730100/inserting-existing-value-into-another-table-with-web-api-and-entity-framework-co) – semiColon

0

question est: On dirait que votre clé est pas unique

Assurez-vous annoter votre colonne de clé primaire clé avec

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Son dire essentiellement à ef que la clé est générée par db

Vous pouvez également

Ajouter une colonne supplémentaire Id qui est généré dynamiquement à l'aide d'annotation indiqué précédemment

+0

Non. La clé dupliquée erreur révèle qu'une entité existante est réinsérée. Cela ne devrait pas être "résolu" en générant une nouvelle clé et en introduisant ainsi des doublons dans la base de données. Cela devrait être * prévenu *. –