EntityFramework 4.0 POCO代理问题

时间:2010-08-15 22:57:05

标签: c# .net entity-framework entity-framework-4 poco

我看到很多人都在问一个类似的问题,但不是这个问题。我正在尝试用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);
}

我做错了什么?谢谢!

2 个答案:

答案 0 :(得分:1)

看起来您想添加一个新的代理对象,以便EF可以注意到对它的更改。

正如StriplingWarrior CreateObject<T>所提到的,只需创建一个代理版本的T,您必须添加它(用于插入)或附加它(用于更新)以便EF了解它。

在代码中的行之间读取它看起来像是要插入吗?

如果确实如此,甚至不需要代理。

为什么呢?

嗯,您不需要属性级别更改跟踪(即知道哪些属性已更改),您需要知道的是对象是新的并且应该插入。

添加通话ctx.MyEntities.Add(...)告诉EF。

对于插入来说,这就足够了:

var entity = new MyEntity();
... // set some props
ctx.MyEntities.Add(entity);
... // sets some more props
ctx.SaveChanges(); 

或者这个

var entity = ctx.CreateObject<MyEntity>();
... // set some props
ctx.MyEntities.Add(entity);
... // sets some more props
ctx.SaveChanges(); 

都会奏效。但前者更容易理解。

希望这有帮助

Alex(微软)

答案 1 :(得分:1)

我对代理没有做太多,但看起来你期望它跟踪一个没有持久状态的对象的变化。

CreateEntity实际上只是创建了对象。这与说“新MyEntity”没什么不同。因此,您必须将该实体添加到上下文并保存更改,然后才能跟踪任何真正的“状态”:

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