Search code examples
entity-frameworkwcf-ria-services

Exception when adding more than one entity at once


Whenever I do something like the following:

public class MyDto
{
    [Key]
    public int ID { get; set; }

    public int ParentID { get; set; }

    public String Name { get; set; }
}

MyDataContext dataContext = new MyDataContext();

MyParentDto myParentDto; // <-- Existing parent DTO querried from the server. Has a relation to MyDto on MyDto.ParentID == MyParentDto.ID.
List<MyDto> myDtos = new List<MyDto>();

myDtos.Add(new MyDto
    {
        Name = "First MyDto!"
    });

myDtos.Add(new MyDto
    {
        Name = "Second MyDto!"
    });

// Some time later.


foreach (var myDto in myDtos)
{
    myDto.ParentID = myParentDto.ID;
    dataContext.MyDtos.Add(myDto);
}

dataContext.SubmitChanges(OnMyCallback)

I get the following vague exception, but my data submits just fine:

System.ServiceModel.DomainServices.Client.DomainOperationException: Submit operation failed.  An entity with the same identity already exists in this EntitySet.  

The stack trace ends with:

System.ServiceModel.DomainServices.Client.EntitySet.AddToCache(Entity entity)
System.ServiceModel.DomainServices.Client.Entity.AcceptChanges()

Both MyDto instances are set to Detached before they are added to dataContext and New afterwards. If I reduce the number of added MyDto instances to one, I get no error. If I call SubmitChanges in between the two adds. Again, both of the MyDto instances are added to the database just fine, but the client crashes with the Exception. What is going on? Thanks.

Edits:

// On the server

[Insert]
public void InsertMyDto(MyDto a_myDto) // <- Yes I prefix. :p
{
    try
    {
        MyEntity myEntity = new MyDto
        {
            ParentID = a_myDto.ParentID,
            Name = a_myDto.Name
        }   

        ObjectContext.MyEntities.AddObject(myEntity);
        ObjectContext.SaveChanges();

    }
    catch (Exception)
    {
        throw; // <- Never hits this spot.
    }
}

// Call back

public void OnMyCallback(SubmitOperation a_submitOperation)
{
        if (a_submitOperation.HasError)
            throw a_submitOperation.Error; // <- It doesn't matter if I have this or not, the client crashes anyway.

        // Other stuff that is not hit because it throws the exception above.
}

Solution

  • I found that the solution to my problem is to save the ID back to the dto when the entity is saved. Like this:

    [Insert]
    public void InsertMyDto(MyDto a_myDto) // <- Yes I prefix. :p
    {
        try
        {
            MyEntity myEntity = new MyDto
            {
                ParentID = a_myDto.ParentID,
                Name = a_myDto.Name
            }   
    
            ObjectContext.MyEntities.AddObject(myEntity);
            ObjectContext.SaveChanges();
    
            a_myDto.ID = myEntity.ID; // <- Solution
    
        }
        catch (Exception)
        {
            throw; // <- Never hits this spot.
        }
    }