none
更新记录的时候,ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象 RRS feed

  • 问题

  • 更新记录的时候,ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象错误:

    IOC   ,  repository , ef4  mvc3   

     

    上代码:

    class Repository<T>

    public class Repository<T> : IDisposable, IRepository<T> where T:class
        {
            private MagicContext objectContext;
            private DbSet<T> dbset;


            public Repository(MagicContext objContext)
            {
                objectContext = objContext;
                if (this.objectContext == null)
                {
                    throw new InvalidOperationException("dbcontext should not be null");
                }
                this.dbset = objectContext.Set<T>();
            }


            public T Add(T entity)
            {           
                dbset.Add(entity);
                return entity;
            }

            public void Attach(T entity)
            {
                dbset.Attach(entity);
            }


            public T Single(Func<T,bool> pred)
            {
                var obj = dbset.AsNoTracking().Single(pred);
                return obj;
            }

            public T SingleOrDefault(Func<T, bool> pred)
            {
                var obj = dbset.AsNoTracking().SingleOrDefault(pred);
                return obj;
            }

            public T First(Func<T, bool> pred)
            {
                var obj = dbset.AsNoTracking().First(pred);
                return obj;
            }

            public T FirstOrDefault(Func<T, bool> pred)
            {
                var obj = dbset.AsNoTracking().FirstOrDefault(pred);
                return obj;
            }

            public bool Any(Func<T, bool> pred)
            {
                bool obj = dbset.Any(pred);
                return obj;
            }

            public IQueryable<T> Where(Func<T, bool> pred)
            {
                return dbset.Where(pred).AsQueryable();
            }

            public void Delete(T entity)
            {
                dbset.Remove(entity);
            }


            public T Find(object Key)
            {
                return dbset.Find(Key);
            }


            public IEnumerable<T> ToList()
            {
                return dbset.ToList();
            }

            public void Update(T entity)
            {
               
                dbset.Attach(entity);
                objectContext.Entry(entity).State = EntityState.Modified;           
            }


            public void SaveChange()
            {
                objectContext.SaveChanges();
            }

            public void Dispose()
            {
                if (this.objectContext != null)
                {
                    this.objectContext.Dispose();
                }
            }

     

    interface IRepository<T>

        public interface IRepository<T> where T : class
        {
            T Add(T entity);
            void Attach(T entity);
            void SaveChange();
            IQueryable<T> Where(Func<T, bool> pred);
            void Delete(T entity);
            void Dispose();
            T Find(object Key);
            IEnumerable<T> ToList();
            void Update(T entity);
            T Single(Func<T,bool> pred);
            T SingleOrDefault(Func<T, bool> pred);
            T First(Func<T, bool> pred);
            T FirstOrDefault(Func<T, bool> pred);
            bool Any(Func<T, bool> pred);
        }

     

    interface IArticleService

        public interface IArticleService
        {
            Article Create(Article entity);
            void Delete(Guid id);
            void Modify(Article entity);
            IEnumerable<Article> ToList();
            Article Single(Func<Article, bool> pred);

        }

    class ArticleService

        public class ArticleService:IArticleService
        {
            IRepository<Article> ArticleRepository = new Repository<Article>(new MagicContext());

            public Article Create(Article entity)
            {
                var obj = ArticleRepository.Add(entity);
                ArticleRepository.SaveChange();

                return obj;
            }

            public void Delete(Guid id)
            {
                var obj = ArticleRepository.Single(x=>x.CategoryID == id);
                ArticleRepository.Delete(obj);
                ArticleRepository.SaveChange();

            }

            public void Modify(Article entity)
            {
                ArticleRepository.Update(entity);
                ArticleRepository.SaveChange();
            }

            public IEnumerable<Article> ToList()
            {
                return ArticleRepository.ToList();
            }

            public Article Single(Func<Article, bool> pred)
            {
                var obj = ArticleRepository.Single(pred);
                return obj;
            }
        }

     

     

    class ArticleController

     

        public class ArticleController : Controller
        {
            private readonly IArticleCategoryService articleCategoryService;
            private readonly IArticleService articleService;


            public ArticleController(IArticleCategoryService articleCategoryService, IArticleService articleService)
            {
                this.articleCategoryService = articleCategoryService;
                this.articleService = articleService;
            }

            [HttpGet]
            public ActionResult ModifyArticle(Guid id)
            {
                var obj = articleService.Single(x => x.ArticleID == id);
                return View(obj);
            }

            [ValidateInput(false)]
            [HttpPost]
            public ActionResult ModifyArticle(Guid id, Article entity)
            {
                if (ModelState.IsValid)
                {
                    articleService.Modify(entity);

                    return RedirectToAction("DefaultArticle");
                }
                return View();
            }

    }

    错误提示:

     

    “/”应用程序中的服务器错误。

    ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

    说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

    异常详细信息: System.InvalidOperationException: ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

    源错误:

     

    行 93:         {
    行 94:             
    行 95:             dbset.Attach(entity);
    行 96:             objectContext.Entry(entity).State = EntityState.Modified;            
    行 97:         }


    源文件: D:\Magic\Magic.Data\Infrastructure\Repository.cs    行: 95

     

     

    在网上看了网的帖子, 使用无跟踪AsNoTracking(),但是还是不行, 各位大侠,SOS。。。


    2011年11月28日 4:57

答案

  • 我用  code first   和你的是不有区别啊。。 。    我没有找到你说的东东 。。。。

    如果你用Code-First的话,以后请先说清楚,不是原来的EF了!那么请这样做:

    public void Modify(Article entity)
    {
     
     using (YourEntityContenxt ds = new YourEntityContenxt ())
                {
                    ds.Entry<Article >(new Article { Property1= entity.Value1, Property2= entity.Value2,……,propertyN=entity.ValueN}).State = EntityState.Modified;
                    ds.SaveChanges();
                }
    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年11月28日 8:58
    版主

全部回复

  • 因为每一个EntityFramework中都有ObjectStateManager,用来管理每一个映射实体的管理器,每一个实体都有一个Entity状态,用于记载当前自身的状态。其不允许一个实体被多个EntityFramework(多个ObjectManager)进行操作。建议:

    public void Modify(Article entity)
    {
     ArticleRepository.Articles.ApplyChanges(entity);   //用新对象替换之前内部的老对象
     ArticleRepository.SaveChange();
    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年11月28日 5:40
    版主
  • 大侠,我的那个里面找不到 applyChanges 这个东东。。。
    2011年11月28日 5:51
  • 大侠,我的那个里面找不到 applyChanges 这个东东。。。


    这样做:

    public void Modify(Article entity)
    {
     你的EntityFramework的实体.ApplyCurrentValues("你的EntityFramework的entitySetName",entity); //用新对象替换之前内部的老对象
    ArticleRepository.SaveChange();
    }

    你的EntityFramework的entitySetName可以通过双击生成的EntityFramework的实体,然后选中某一个class模型,在右边的属性中可以看到。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年11月28日 5:55
    版主
  • 我用  code first   和你的是不有区别啊。。 。    我没有找到你说的东东 。。。。

     

     

    2011年11月28日 8:47
  • 我用  code first   和你的是不有区别啊。。 。    我没有找到你说的东东 。。。。

    如果你用Code-First的话,以后请先说清楚,不是原来的EF了!那么请这样做:

    public void Modify(Article entity)
    {
     
     using (YourEntityContenxt ds = new YourEntityContenxt ())
                {
                    ds.Entry<Article >(new Article { Property1= entity.Value1, Property2= entity.Value2,……,propertyN=entity.ValueN}).State = EntityState.Modified;
                    ds.SaveChanges();
                }
    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年11月28日 8:58
    版主