1

I am trying to inset a User into a Conversation Table. A conversation has a set collection of Users as a member variable. It is this variable that is giving me trouble. When I try to Post a Conversation I am getting the error:

"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.",

I am trying to insert an existing User into a Conversation but it looks like it is trying to insert a new User which is causing a duplicate error.

Conversation class:

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

The User is defined as:

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

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

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

My controller is defined as:

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

Any input would be appreciated! :)

EDIT I never included the outter exception:

"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.",
0

2 Answers 2

1

The problem is that ...

db.Conversations.Add(convo);

... recursively marks all entities that belong to convo as Added (when they're not yet attached to the context). So it tries to insert new User records instead of just setting the foreign key to existing ones.

The solution is to attach the Users to the context before adding the conversation:

foreach(var user in convo.Members)
{
     db.Entry(user).State = System.Data.Entity.EntityState.Unchanged;
}
db.Conversations.Add(convo);
Sign up to request clarification or add additional context in comments.

3 Comments

That seems to have solved that error as I am not getting the same exception... Thank you so much! However I cannot be sure as I have, yet again, ran into another error which may, again, warrant to a question of its own! "ExceptionMessage": "Unable to cast object of type 'System.Collections.Generic.List1[AcademicAssistant.Models.User]' to type 'AcademicAssistant.Models.User'.",` This must be because of the way it is being stored in the database however I do not understand the problem or how to fix it. Shall I post another new question?
Perhaps you could take a look at another similar question of mind please? Here it is
0

Issue is: Looks like your key is not unique

Make sure you annotate your primary key column key with

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Its basically telling to ef that the key is generated by db

Alternatively

Add additional column with Id that is generated dynamically using previously stated annotation

1 Comment

No. The duplicate key error reveals that an existing entity is reinserted. This should not be "solved" by generating a new key and thus introducing duplicates in the database. It should be prevented.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.