0

VS2012でのデバッグ中にこの例外を受け取りました

同じキーを持つオブジェクトは、ObjectStateManagerにすでに存在します。ObjectStateManagerは、同じキーを持つ複数のオブジェクトを追跡できません。

//_dbSet declaration: 

    private readonly IDbSet<T> _dbSet;


//Method parameter

    public virtual void Update(T entity)


//method fragment   



 public virtual void Update(T entity)
    {
        if (Entities == null) return;

        var entry = Entities.Entry(entity);

        switch (entry.State)
        {
            case EntityState.Modified:
                var currentValues = entry.CurrentValues.Clone();
                entry.Reload();
                switch (entry.State)
                {
                    case EntityState.Detached:
                        Entities.Entry(entry).State = EntityState.Modified;
                        break;
                    default:
                        entry.Reload();
                        entry.CurrentValues.SetValues(currentValues);
                        break;
                }
                break;
            case EntityState.Detached:
                _dbSet.Attach(entity); /*Here is the thing*/
                entry.CurrentValues.SetValues(entity);
                break;
        }
        Entities.Commit();
    }

私は、結果が得られずに、DbFactory、Unit of Work、DI、GenericRepositoryのパターンで楽観的並行性を解決しようとしてほぼ1週間を費やしました。

4

3 に答える 3

0

例外メッセージは十分に明確だと思います。

同じキーを持つエンティティ(つまり、同じデータベースレコードにマップするエンティティ)は、ターゲットにすでにロードおよびアタッチされていますDbSet

その場合に何をするかは完全にあなた次第です。

  • entityすでにロードされている同等のエントリを取得し、インスタンス(またはより複雑なもの)に一致するように添付された同等の値を変更できます。
  • entity同等のロードされたエントリをデタッチして、代わりにパラメータをアタッチできます。
  • あなたはそれをスキップすることができます。
于 2013-01-18T15:15:56.617 に答える
0

コードは悪臭を放ちます。

最初のswitchステートメントは、entry.Stateand を使用して、エンティティが変更された状態か分離された状態かをチェックします。その後、変更された case では、新しい switch ステートメントが作成され、エンティティが切り離されているか、または他の状態にあるかを確認します。

例外は、楽観的並行性について何も述べていません。代わりに、エンティティをオブジェクト コンテキストにアタッチしようとしており、同じキーを持つエンティティがコンテキストに既に存在することが示されています。

于 2013-01-18T15:16:53.357 に答える
0

貴重な時間を私の頭取りのために割いてくださったすべての方々に感謝します。これは、ジェネリック リポジトリ パターンでの並行 Update メソッドの最終的な解決策を明らかにする新しい投稿です。この記事のおかげで何も失われませんでした: Seeking Entity's Key by Attribute Along

とても役に立ちました: RoccoC5


private object GetKeyValue(T entity)
    {
        var key =
            typeof(T).GetProperties().FirstOrDefault(
                p => p.GetCustomAttributes(typeof(KeyAttribute), true).Length != 0);
        return (key != null) ? key.GetValue(entity, null) : null;
    } 

public virtual void Update(T entity) { if (Entities == null) return;

        var key = GetKeyValue(entity);
        var originalEntity = _dbSet.Find(key);
        Entities.Entry(originalEntity).CurrentValues.SetValues(entity);
        Entities.Commit();
   }
于 2013-01-30T21:34:59.193 に答える