1

I'm getting a really strange glitch and I believe entity framework is to blame. Here's the basic scenario thats going on. I have an entity object, Foo, with a navigation property collection, Bar. Foo in this context is being tracked by entity frameworks change tracking. I run the following code, but the result is very strange

var NewBars = CreateBars(); //CreateBars returns a List<Bars> with two items

//After this code is ran, Foo.Bars AND NewBars will both be lists with 4 items.
//I think its because Foo.Bars has dynamic proxies, entity framework edits bars
//To re-insert the overwritten proxies. 
Foo.Bars = NewBars;

If I put a breakpoint at the var NewBars = CreateBars() line, and step through it piece by piece, everything will come out as expected. Foo.Bars will be a two item list, NewBars will be a two item list. But If I run execution with no breakpoints, or if I break point after I set Foo.Bars = NewBars, then both of these lists miraculously change to 4 item lists. Its weird to me that even the right hand value list is being changed.

At one point, even when I had the execution stopped at a breakpoint, I checked the contents of newbars and it was 2 the first time I looked, and then 4 the next time I looked. It changed while the program was at a halt, so I know theres something going on behind the scenes.

The problem is that because it keeps reinserting the proxies, Im getting primary key conflicts. If the proxies don't re-insert, then everything is fine. Im just wondering, how do I remedy this problem? I just simply want to set Foo.Bars to a new list of items. Any direction on this issue would be greatly appreciated! Thanks!

Vance Palacio
  • 1,280
  • 12
  • 17

1 Answers1

1

What do you want to happen to the Bars that are in Foo.Bars before you assign newBars?

You need to deal with them in some way. They are represeted by rows in a Bar table in your database, right?

You could remove these old Bars entirely with something like:

dbContext.Bars.RemoveRange(Foo.Bars);
dbContext.SaveChages();

then assign your new bars:

Foo.Bars = NewBars;
dbContext.SaveChanges();

Alternatively if you still want the old Bars to exist in the db but just not be linked to Foo then you can do:

Foo.Bars=null;
Foo.Bars = newBars;
dbContext.SaveChanges();

(Of course this assumes your db schema allows this without violating any constraints)

Stewart_R
  • 13,764
  • 11
  • 60
  • 106
  • Well, I guess what I was thinking was because in some cases, CreateBars would probably generate what was already in the list, and other times maybe it would generate a different list. But Basically in either case, I just basically wanted to write over whatever values were already in the database. And then if there were new values, to just add them in. But I guess I could always just clear out the lists before I generate new sets – Vance Palacio Nov 22 '14 at 19:29
  • You could also amend `CreateBars()` to pull the existing entries rather than creating new ones with the same id. If you do somethign like `newBar = dbContext.Bars.Find(id)` rather than 'newBar = new Bar{ ... ....}` you shouldnt have the same problem adding the results in the returned list – Stewart_R Nov 22 '14 at 20:00