2

以下のコードからわかるように、AsNoTracking を使用してオブジェクトを取得します。次に、ObjectSateManager を使用して何が起こっているかを確認し、l* コレクションで何も追跡されていないことを確認できますが、まだ取得しています

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

何か案は?

========================================
BasketRepository レポ = new BasketRepository();

            var ba = repo.GetById(8);

            var bpro = new BasketProduct(ba, ba.BasketProducts.First().Product, 3);

            repo.AddToBasket(bpro);
           repo.Save();

==================================

    public Basket GetById(int basketId)
    {
        // eager-load product info
        var basket = dbContext.Baskets.Include("BasketProducts")
                                      .Include("BasketProducts.Product.Brand").AsNoTracking().SingleOrDefault(b => b.BasketId == basketId);;
        return basket;
    }

======================================

  public void AddToBasket(BasketProduct product)
    {
        var ctx = ((IObjectContextAdapter)dbContext).ObjectContext;
        ObjectStateManager objectStateManager = ctx.ObjectStateManager;
        var l1 = objectStateManager.GetObjectStateEntries(EntityState.Added);
        var l2 = objectStateManager.GetObjectStateEntries(EntityState.Modified);
        var l3 = objectStateManager.GetObjectStateEntries(EntityState.Deleted);
        //var l4 = objectStateManager.GetObjectStateEntries(EntityState.Detached);
        var l5 = objectStateManager.GetObjectStateEntries(EntityState.Unchanged);

        var existingProductInBasket = dbContext.BasketProducts.AsNoTracking().SingleOrDefault(b => b.BasketId == product.BasketId && b.ProductId == product.ProductId);
        var l6 = objectStateManager.GetObjectStateEntries(EntityState.Added);
        var l7 = objectStateManager.GetObjectStateEntries(EntityState.Modified);
        var l8 = objectStateManager.GetObjectStateEntries(EntityState.Deleted);
        //var l4 = objectStateManager.GetObjectStateEntries(EntityState.Detached);
        var l9 = objectStateManager.GetObjectStateEntries(EntityState.Unchanged);

        //objectStateManager.
        dbContext.Entry<BasketProduct>(product).State = existingProductInBasket == null ? EntityState.Added : EntityState.Modified;

    }
4

2 に答える 2

0

それは実際には悪いことでした。EFによって物事がどのようにアタッチされ、追跡されるかという考えに慣れるのは、概念的に少し難しい場合があります。秘密は、オブジェクトグラフ(他のオブジェクトとの関係を持つオブジェクト)がある場合、グラフのオブジェクトが状態Xにアタッチされるたびに、グラフ内の他のすべてのオブジェクトもその状態でアタッチされているように見えることを覚えておいてください。

私のシナリオでは、非常に愚かなことにvar bpro = new BasketProduct(ba、ba.BasketProducts.First()。Product、3);を使用していました。データベースに実際に存在し、バスケットとその製品を含むオブジェクトグラフの一部であるテスト製品を作成します。この「新しい」バスケットを取り付けようとしたとき、EFは、同じキーを持つオブジェクトが添付されたグラフにすでに存在することを正しく不満に思っていました。

于 2012-12-04T17:49:04.120 に答える