首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AsNoTracking和ObjectStateManager的实体框架错误

AsNoTracking和ObjectStateManager的实体框架错误
EN

Stack Overflow用户
提问于 2012-12-04 07:38:39
回答 2查看 1.5K关注 0票数 2

从下面的代码中可以看到,我使用AsNoTracking来获取对象。然后,我甚至使用ObjectSateManager来查看发生了什么,并且我在l*集合中看不到任何被跟踪的东西,但是我仍然得到

“ObjectStateManager中已存在具有相同密钥的对象。ObjectStateManager无法跟踪具有相同密钥的多个对象”。

有什么想法吗?

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

代码语言:javascript
复制
     BasketRepository repo = new BasketRepository();
代码语言:javascript
复制
            var ba = repo.GetById(8);

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

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

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

代码语言:javascript
复制
    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;
    }

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

代码语言:javascript
复制
  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;

    }
EN

回答 2

Stack Overflow用户

发布于 2014-03-29 03:59:30

当您使用asNoTracking()时,您会得到一个无法使用EntityState.Modified正常更新的未连接实体。然后,一个技巧是将缓存的实体值替换为非缓存的实体值。

下面是我在需要使用asNoTracking的特殊情况下使用的源代码。它可以是

代码语言:javascript
复制
private T ReplaceEntity(T cachedEntity, T nonCachedEntity) {

     dbContext.Entry(cachedEntity).CurrentValues.SetValues(nonCachedEntity);

     return cachedEntity;
}

常见的用法可以是:

代码语言:javascript
复制
public virtual T FindFirstBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate, bool asNoTracking = false)
{
     if (asNoTracking)
     {
          T cachedEntity = dbContext.Set<T>().FirstOrDefault(predicate);
          T nonCachedEntity = dbContext.Set<T>().AsNoTracking().FirstOrDefault(predicate);

          return ReplaceEntity(cachedEntity, nonCachedEntity);
     }
     return dbContext.Set<T>().FirstOrDefault(predicate);
}

针对您的情况:

代码语言:javascript
复制
var cachedEntity = dbContext.BasketProducts.SingleOrDefault(b => b.BasketId == product.BasketId && b.ProductId == product.ProductId);
var nonCachedEntity = dbContext.BasketProducts.AsNoTracking().SingleOrDefault(b => b.BasketId == product.BasketId && b.ProductId == product.ProductId);

var product= ReplaceEntity(cachedEntity, nonCachedEntity);
dbContext.Entry<BasketProduct>(product).State = EntityState.Modified;

希望它能有所帮助!!

票数 1
EN

Stack Overflow用户

发布于 2012-12-05 01:49:04

这真是太糟糕了。从概念上来说,要习惯于EF如何附加和跟踪事物的想法可能有点困难。秘诀是要记住,如果你有一个对象图(与其他对象有关系的对象),只要图中的一个对象被附加了状态X,那么图中的所有其他对象似乎也在那个状态下附加了。

在我的场景中,我非常愚蠢地使用var bpro = new BasketProduct(ba,ba.BasketProducts.First().Product,3);来创建一个实际上已经存在于数据库中的测试产品,它是包含篮子及其产品的对象图的一部分。当我试图附加这个“新”篮子时,EF正确地抱怨说,在附加的图形中已经存在一个具有相同键的对象!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13693757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档