积极答复者
更新记录的时候,ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象

问题
-
更新记录的时候,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日 5:07
答案
-
我用 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我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处- 已编辑 ThankfulHeartModerator 2011年11月30日 2:29
- 已标记为答案 Paul Zhou 2011年12月5日 5:34
全部回复
-
因为每一个EntityFramework中都有ObjectStateManager,用来管理每一个映射实体的管理器,每一个实体都有一个Entity状态,用于记载当前自身的状态。其不允许一个实体被多个EntityFramework(多个ObjectManager)进行操作。建议:
public void Modify(Article entity)
{
ArticleRepository.Articles.ApplyChanges(entity); //用新对象替换之前内部的老对象
ArticleRepository.SaveChange();
}QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处 -
大侠,我的那个里面找不到 applyChanges 这个东东。。。
这样做:public void Modify(Article entity)
{
你的EntityFramework的实体.ApplyCurrentValues("你的EntityFramework的entitySetName",entity); //用新对象替换之前内部的老对象
ArticleRepository.SaveChange();
}你的EntityFramework的entitySetName可以通过双击生成的EntityFramework的实体,然后选中某一个class模型,在右边的属性中可以看到。
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处- 已编辑 ThankfulHeartModerator 2011年11月28日 5:59
-
我用 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我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处- 已编辑 ThankfulHeartModerator 2011年11月30日 2:29
- 已标记为答案 Paul Zhou 2011年12月5日 5:34