简体   繁体   English

EntityFramework 4.0 POCO代理问题

[英]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. 我正在尝试做一些我希望POCO代理相对简单的事情。

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 newEntity = 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! 谢谢!

It looks like you want to add a new proxy object so EF can notice changes to it. 看来您想添加一个新的代理对象,以便EF可以注意到它的更改。

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. 如StriplingWarrior所述, CreateObject<T>仅创建CreateObject<T>的代理版本,您必须添加(用于插入)或附加(用于更新),EF才能了解它。

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 (ie 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. 添加调用ctx.MyEntities.Add(...)告诉EF。

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) 亚历克斯(微软)

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. CreateEntity实际上只是创建对象。 It's no different than saying "new MyEntity". 说“ 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.
    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM