Reputation: 9911
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
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
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