Jordan
Jordan

Reputation: 9911

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.
}

Upvotes: 2

Views: 851

Answers (2)

Jordan
Jordan

Reputation: 9911

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.
    }
}

Upvotes: 2

sebagomez
sebagomez

Reputation: 9609

Have you tried setting the parent instead of it's ID?

foreach (var myDto in myDtos)
{
    myDto.Parent = myParentDto;
} //Assuming myParentDto is already in the context, if not add it first

Edit: I'm taking a wild guess here but could you check the HashCode of the objects right before the Exception occurs? You could also try overriding the GetHashCode() method to return something random every time just to test those are the exact entities involved in the exception.

Upvotes: 1

Related Questions