EntityFramework 4.0 POCO Proxy Problem
I see a lot of people asking a similar question, but not this exact one. I'm trying to do what I would hope would be relatively simple with POCO proxies.
using (var context = new MyObjectContext())
{
context.ContextOptions.ProxyCreationEnabled = true;
// this does indeed create an instance of a proxy for me...
// something like Product_SomeBunchOfNumbersForProxy
var newEntit开发者_开发百科y = context.CreateObject<MyEntity>();
// throws exception because newEntity is not in ObjectStateManager...why??
context.ObjectStateManager.GetObjectStateEntry(newEntity);
// ok, well I guess let's add it to the context manually...
context.AddObject("Model.Products", newEntity);
// doesn't throw an exception...I guess that's good
var state = context.ObjectStateManager.GetObjectStateEntry(newEntity);
// prints System.Data.EntityState.Unchanged...oh...well that's not good
Console.WriteLine(state.State);
// let's try this...
context.DetectChanges();
// doesn't throw an exception...I guess that's good
state = context.ObjectStateManager.GetObjectStateEntry(newEntity);
// prints System.Data.EntityState.Unchanged...still no good...
Console.WriteLine(state.State);
// dunno, worth a shot...
context.Refresh(RefreshMode.ClientWins);
// throws exception because newEntity is not in ObjectStateManager...
// that didn't help...
state = context.ObjectStateManager.GetObjectStateEntry(newEntity);
}
What am I doing wrong? Thanks!
I haven't done much with proxies, but it looks like you're expecting it to track changes on an object that has no persistent state yet.
CreateEntity really just creates the object. It's no different than saying "new MyEntity". So you have to add that entity to the context and save the changes before it has any true "state" to track against:
using (var context = new MyObjectContext())
{
context.ContextOptions.ProxyCreationEnabled = true;
var newEntity = context.CreateObject<MyEntity>();
context.Add(newEntity);
context.SaveChanges();
// now GetObjectStateEntry(newEntity) should work just fine.
// ...
}
It looks like you want to add a new proxy object so EF can notice changes to it.
As mentioned by StriplingWarrior CreateObject<T>
simply creates a proxied version of T, you have to Add it (for inserts) or Attach it (for updates) for EF to learn about it.
Reading between the lines in your code it looks like you want to do an insert?
If that is indeed the case a Proxy isn't even really required.
Why?
Well you don't need property level change tracking (i.e. to know what properties have changed) all you need to know is that the object is new and should be inserted.
Add calling ctx.MyEntities.Add(...)
tells EF that.
Which means for inserts this is enough:
var entity = new MyEntity();
... // set some props
ctx.MyEntities.Add(entity);
... // sets some more props
ctx.SaveChanges();
Or this
var entity = ctx.CreateObject<MyEntity>();
... // set some props
ctx.MyEntities.Add(entity);
... // sets some more props
ctx.SaveChanges();
will both work. But the former is easier to understand.
Hope this helps
Alex (Microsoft)
精彩评论