实体对象不能由通用存储库中的IEntityChangeTracker的多个实例引用 [英] Entity object cannot be referenced by multiple instances of IEntityChangeTracker in a generic repository
问题描述
我在这个 tugberkugurlu ,这是...
public interface IGenericRepository&T ;其中T:class {
IQueryable< T>得到所有();
IQueryable< T> FindBy(表达式< Func< T,bool>>谓词);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
和此通用存储库
public abstract class GenericRepository< C,T> :
IGenericRepository< T>其中T:class C:DbContext,new(){
private C _entities = new C();
public C Context {
get {return _entities; }
set {_entities = value; }
}
public virtual IQueryable< T> GetAll(){
IQueryable< T> query = _entities.Set< T>();
返回查询;
}
public IQueryable< T> FindBy(System.Linq.Expressions.Expression< Func< T,bool>> predicate){
IQueryable< T> query = _entities.Set< T>()。Where(predicate);
返回查询;
}
public virtual void Add(T entity){
_entities.Set< T>()。Add(entity);
}
public virtual void Delete(T entity){
_entities.Set&T;()。Remove(entity);
}
public virtual void Edit(T entity){
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save(){
_entities.SaveChanges();
}
}
现在可以这样使用...
public class FooRepository:
GenericRepository&FooBarEntities,Foo>,IFooRepository {
public Foo GetSingle(int fooId){
var query = GetAll()。FirstOrDefault(x => x.FooId == fooId);
返回查询;
}
}
现在,一切都好,直到我有一个自我引用的实体,像这样...
public class Question
{
[Key]
public string QuestionID {get;组; }
public string QuestionNumber {get;组; }
public string Message {get;组; }
public DateTime? DatePosted {get;组; }
public DateTime?修改{get;组; }
public bool HasSubgroups {get;组; }
public string ApplicationUserId {get;组; }
[ForeignKey(ApplicationUserId)]
public virtual ApplicationUser ApplicationUser {get;组; }
public string PaperID {get;组; }
[ForeignKey(PaperID)]
public virtual PaperEntity Paper {get;组; }
public ICollection< QuestionTag>标签{get;组; }
public ICollection< QuestionVote>投票{get;组; }
public virtual ICollection< Answer>答案{get;组; }
public virtual ICollection< QuestionComment> QuestionComments {get;组; }
public string ParentQuestionID {get;组; }
[ForeignKey(ParentQuestionID)]
public virtual Question QuestionReference {get;组; }
public virtual ICollection< Question>问题{get;组; }
}
如您所见,我的模型允许我有子问题一个问题这是我如何实现它...
dynamic model = modela;
string q_id = model.QuestionID.ToString();
var question = q_id.IsNullOrEmpty()? null:await questionRepository.FindBy(id => id.QuestionID == q_id);
if(question == null)
{
question = new Question
{
QuestionID = Guid.NewGuid()ToString(D )
QuestionNumber = model.ParentQuestionNumber,
PaperID = model.PaperID,
Message = model.QuestionTitle,
ApplicationUserId = userid,
DatePosted = DateTime.UtcNow,
标签=新列表< QuestionTag>()
};
await questionRepository.Add(question);
}
var questionQuestion = new Question
{
QuestionID = Guid.NewGuid()ToString(D),
ParentQuestionID =问题。 QuestionID,
QuestionNumber = model.QuestionNumber,
PaperID = question.PaperID,
Message = model.Message,
ApplicationUserId = userid,
DatePosted = DateTime.UtcNow,
标签=新列表< QuestionTag>()
};
question.Questions = new List< Question> {questionQuestion};
await questionRepository.Update(question);
await questionRepository.Save();
之后,我能够保存第一个子问题,第二个问题引发错误。 ..
_ctx.Entry(entity).State = EntityState.Modified;
说...
EntityFramework.dll中发生类型为System.InvalidOperationException的第一次机会异常
附加信息:实体对象不能被IEntityChangeTracker的多个实例引用。
我甚至尝试使用 IDisposable
code> GenericRepository 没有运气...任何提示嗅觉帮助将高度赞赏...
我从此示例 ...
public class UnitOfWork:IDisposable
{
private DbContext context = new DbContext();
私人FooRepository fooRepository;
public FooRepository fooRepository
{
get
{
if(this.fooRepository == null)
{
this.fooRepository = new FooRepository(context);
}
return fooRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private boolwhere = false;
protected virtual void Dispose(bool disposal)
{
if(!this.disposed)
{
if(disposal)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
然后我更改每个存储库以接受上下文
public class FooRepository:
GenericRepository&Foo>,IFooRepository {
public FooRepository (DbContext context):base(context){}
}
i have used a generic interface and repository in this tugberkugurlu, which is...
public interface IGenericRepository<T> where T : class {
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
and this generic repository
public abstract class GenericRepository<C, T> :
IGenericRepository<T> where T : class where C : DbContext, new() {
private C _entities = new C();
public C Context {
get { return _entities; }
set { _entities = value; }
}
public virtual IQueryable<T> GetAll() {
IQueryable<T> query = _entities.Set<T>();
return query;
}
public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public virtual void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public virtual void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save() {
_entities.SaveChanges();
}
}
which can now be used like this...
public class FooRepository :
GenericRepository<FooBarEntities, Foo>, IFooRepository {
public Foo GetSingle(int fooId) {
var query = GetAll().FirstOrDefault(x => x.FooId == fooId);
return query;
}
}
now, all is, or was well until i had a self referencing entity, like this...
public class Question
{
[Key]
public string QuestionID { get; set; }
public string QuestionNumber { get; set; }
public string Message { get; set; }
public DateTime? DatePosted { get; set; }
public DateTime? Modified { get; set; }
public bool HasSubgroups { get; set; }
public string ApplicationUserId { get; set; }
[ForeignKey("ApplicationUserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
public string PaperID { get; set; }
[ForeignKey("PaperID")]
public virtual PaperEntity Paper { get; set; }
public ICollection<QuestionTag> Tags { get; set; }
public ICollection<QuestionVote> Votes { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
public virtual ICollection<QuestionComment> QuestionComments { get; set; }
public string ParentQuestionID { get; set; }
[ForeignKey("ParentQuestionID")]
public virtual Question QuestionReference { get; set; }
public virtual ICollection<Question> Questions { get; set; }
}
and as you can see, my model allows me to have sub-questions to a question. and this is how i try to implement it...
dynamic model = modela;
string q_id = model.QuestionID.ToString();
var question = q_id.IsNullOrEmpty() ? null : await questionRepository.FindBy(id => id.QuestionID == q_id);
if (question == null)
{
question = new Question
{
QuestionID = Guid.NewGuid().ToString("D"),
QuestionNumber = model.ParentQuestionNumber,
PaperID = model.PaperID,
Message = model.QuestionTitle,
ApplicationUserId = userid,
DatePosted = DateTime.UtcNow,
Tags = new List<QuestionTag>()
};
await questionRepository.Add(question);
}
var questionQuestion = new Question
{
QuestionID = Guid.NewGuid().ToString("D"),
ParentQuestionID = question.QuestionID,
QuestionNumber = model.QuestionNumber,
PaperID = question.PaperID,
Message = model.Message,
ApplicationUserId = userid,
DatePosted = DateTime.UtcNow,
Tags = new List<QuestionTag>()
};
question.Questions = new List<Question>{questionQuestion};
await questionRepository.Update(question);
await questionRepository.Save();
and after i am able to save the first sub-question, the second question throws an error at...
_ctx.Entry(entity).State = EntityState.Modified;
saying...
A first chance exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
i have even tried using IDisposable
on GenericRepository
without luck...Any hint smelling assistance will be highly appreciated...
i created a UnitOfWork from this example...
public class UnitOfWork : IDisposable
{
private DbContext context = new DbContext();
private FooRepository fooRepository;
public FooRepository fooRepository
{
get
{
if (this.fooRepository == null)
{
this.fooRepository = new FooRepository(context);
}
return fooRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
then i changed each repository to accept a context...
public class FooRepository :
GenericRepository<Foo>, IFooRepository {
public FooRepository(DbContext context) : base(context) {}
}
这篇关于实体对象不能由通用存储库中的IEntityChangeTracker的多个实例引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!