实体框架更新现有对象

时间:2012-06-29 19:29:28

标签: entity-framework entity-framework-4 navigation-properties objectstatemanager

我在我的数据库中添加了一行,然后返回不同的上下文来更新它。我有这门课:

public abstract partial class DataManager<I, C> 
    where C : class, IDomainObject, I, new( ) where I : IDomainObject

C可能是一个EntityObject,但是这个类不知道。

我的保存看起来像这样:

    public virtual bool Save( I _item )
    {
        bool rc = true;
        try
        {
        var set = m_Context.GetObjectSet<I, C>( );
        ObjectStateEntry stateEntry = null;
        if( ! m_Context.ObjectStateManager.TryGetObjectStateEntry( ( C ) _item, out stateEntry ) )
        {
            if( _item is EntityObject )
            {
                    if ( _item.IsNew )
                    {
                        set.AddObject( ( C ) _item );
                    }
                    else
                    {
                        try
                        {
                            set.Attach( ( C ) _item );
                        }
                        catch( Exception ex )
                        {
                            set.ApplyCurrentValues( ( C ) _item );
                        }

依旧......

在我的测试用例中,TryGetObjectStateEntry找不到stateEntry。然而,它是一个EntityObject,它不是新的(IsNew是我的标志),所以它到达了else。这是我的问题:set.Attach抛出此错误

“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象。”

在下一个瞬间,ApplyCurrentValues会抛出这个:

“在ObjectStateManager中找不到具有与提供的对象的键匹配的键的对象。验证提供的对象的键值是否与必须应用更改的对象的键值匹配。”< / p>

这两者都是如此?

更多信息:

_item是由另一个上下文中的Get创建的。然后处理了这种背景。此时,_item有一个EntityState.Unchanged。我对它应用了一些更改,并将其更改为EntityState.Modified。 (我没想到,因为上下文(及其ObjectStateManager)应该已经消失了。)无论如何,一旦它到达Save(上面),它的状态(由调试器报告)是Modified,但我有一个新的背景。如果我此时获得所有ObjectStateEntries(添加,删除,修改,未更改)的列表,那么只有两个,而_item不是其中之一,因为ApplyCurrentValues报告,但它不能被附加,因为“它是那边!“也许问题是它仍然附加到一个旧的ObjectStateManager(可能有一些引用不会让ObjectStateManager处理?)。

2 个答案:

答案 0 :(得分:0)

问题在于,每次初始化db-context时,它都会从数据库和foreach行获取行,并分配实体键。这意味着由2 db-context检索的同一行将具有2个不同的实体键。实体密钥类似于实体框架中的id,它用于代替所讨论实体的ID。但是表的约束虽然保留了(没有重复的主键) 希望这是有道理的。

答案 1 :(得分:0)

问题在于您使用相同的组织附加了两个不同的用户,但是,组织对象在每种情况下都是不同的实例。

如果组织已在数据库中,请尝试:

  1. 将组织的导航属性设置为null并仅设置OrganizationId属性。

  2. 或者从数据库中加载组织实体并将其设置为导航道具。

  3. 如果组织不在DB中:

    使用相同的实例(抛出一个并将其替换为另一个)。