我有两个域对象,它们都相同但具有不同的 PK 属性:
public partial class Maintenance : MaintenanceBase
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int MaintenanceId { get; set; }
public virtual Employee Employee { get; set; }
}
public partial class MyMaintenance : MaintenanceBase
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int RowId { get; set; }
public virtual Employee Employee { get; set; }
}
其余属性继承自基类。我遇到的问题是当尝试在我的后控制器中调用保存更改时,我收到以下错误:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker
这是(基本上)我的控制器方法:
[HttpPost]
public ActionResult SubmitMyMaintenance(IList<MyMaintenance> myMaintenanceList, string userName)
{
foreach (var result in myMaintenanceList)
{
var m = iMyMaintenanceRepository.GetSingle(result.RowId);
Maintenance maintenance = new Maintenance();
// Use Injector to handle mapping between viewmodel and model
maintenance.InjectFrom(m);
try
{
if (ModelState.IsValid)
{
// save the maintenance item
iMaintenanceRepository.Add(maintenance);
iMaintenanceRepository.Save();
// delete the item in MyMaintenance
iMyMaintenanceRepository.Delete(m);
iMyMaintenanceRepository.Save();
}
}
catch (DataException ex)
{
message = ex.InnerException.ToString();
}
}
// refresh the view
var mvm = new MyMaintenanceListViewModel
{
MyMaintenanceList = iMyMaintenanceRepository.FindBy(v => v.CreatedBy.Equals(userName)).ToList(),
Message = "Your maintenance items were successfully added."
};
return View("MyMaintenance", mvm);
}
我怀疑这是因为我在同一个控制器 post 方法中有两个域对象的存储库 ( iMaintenanceRepository
& iMyMaintenanceRepository
) 实例,并且都引用了 Employee 实体。
例如,当我处理 iMyMaintenanceRepository 并创建一个新实例(在最后刷新视图之前)时,我收到关于在 Employee 表中插入空值的错误,我没有插入任何东西。这就是我怀疑 Employee 实体存在于两个不同的数据上下文中的原因。我不知道如何解决它。我发现的所有解决方案似乎都不适用,我认为这更多是我的实施问题。
编辑:存储库
namespace EMMS.Models.Interfaces
{
public interface IMyMaintenanceRepository : IGenericRepository<MyMaintenance>
{
MyMaintenance GetSingle(int RowId);
}
}
namespace EMMS.Models.Repositories
{
public class MyMaintenanceRepository : GenericRepository<AppDBContext, MyMaintenance>, IMyMaintenanceRepository
{
public MyMaintenance GetSingle(int RowId)
{
var query = GetAll().FirstOrDefault(x => x.RowId == RowId);
return query;
}
}
}
namespace EMMS.ViewModels.Repositories
{
public class GenericRepository<C, T> : IDisposable, 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;
}
// enforce referential itegrity
public bool ValueInUse(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _entities.Set<T>().Where(predicate);
int count = query.Count();
return count > 0 ? true : false;
}
public virtual void Add(T entity)
{
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Deleted;
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save()
{
_entities.SaveChanges();
}
private bool disposed = false; // to detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (_entities != null)
{
_entities.Dispose();
}
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
namespace EMMS.ViewModels.Interfaces
{
public interface IGenericRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
bool ValueInUse(System.Linq.Expressions.Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
void Dispose();
}
}