由于“IEntityChangeTracker的多个实例无法引用实体对象,因此我正遇到InvalidOperationException异常”。在EntityFrameWorkRepository.Create()的第一行。找不到引用实体框架实体的对象
我知道这是由于有多个数据库上下文,但在这种情况下,我有点失落,因为代码没有明显的第二个上下文,因为所有数据库访问都通过一个指定的对象,其唯一目的是管理数据库上下文。这是因为所讨论的Web应用程序具有相当的交互性,所以用户不断创建必须保存在数据库中的新对象。这是由于前面的设计使用了锁定和单个上下文的问题,因此代码被重构并且工作,除了所讨论的方法之外。
EF类:
public class EntityFrameWorkRepository<TKey, TEntity> : IDisposable, IRepository<TKey,TEntity> where TEntity: class
{
private readonly IDbContext _context;
private IDbSet<TEntity> _entities;
public EntityFrameWorkRepository()
{
_context = new ApplicationDbContext();
}
private IDbSet<TEntity> Entities
{
get { return _entities ?? (_entities = _context.Set<TEntity>()); }
}
public void Create(TEntity entity)
{
Entities.Add(entity);
_context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
用于所有数据库访问服务对象:
public class Service : IService
{
public const string Persistance = "Persist";
public const int CacheTaskSeconds = 300; //Check every 5 minutes
public const double IdleMinutes = 30.0;
private readonly IKvpRepository<int, SimulationCollection> _simulationCollectionAppStateRepository;
private readonly UserManager<ApplicationUser> _userManager;
public Service(IKvpRepository<int, SimulationCollection> simulationCollectionAppStateRepository)
{
_userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
AddTaskToCache(Persistance, CacheTaskSeconds);
}
public SimulationCollection CreateCollection(Guid userId, string name, string description)
{
using (var _simulationCollectionEFRepository = new EntityFrameWorkRepository<int, SimulationCollectionEntity>())
{
var applicationUser = _userManager.FindById(userId.ToString());
if (applicationUser == null)
throw new ArgumentOutOfRangeException("ApplicationUser matching userId doesn't exist");
var collectionEntity = new SimulationCollectionEntity(applicationUser, name, description);
_simulationCollectionEFRepository.Create(collectionEntity);
return collection;
}
}
}
我试图添加到数据库中的对象:
public class SimulationCollectionEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
public string Name { get; set; }
public virtual ApplicationUser User { get; set; }
public DateTime DateCreated { get; set; }
public string Description { get; set; }
[ForeignKey("SimulationCollectionEntityId")]
public virtual ICollection<SimulationEntity> Simulations { get; set; }
[Obsolete("Only needed for serialization and materialization", true)]
public SimulationCollectionEntity() {}
public SimulationCollectionEntity(ApplicationUser currentUser, string name, string description)
{
User = currentUser;
Name = name;
Description = description;
DateCreated = DateTime.Now;
}
}
有没有一种简单的方法来查看给定的对象可能被附加到哪些上下文hed to?我已经检查过,看看collectionEntity是否附加到_userManager,因为它有一个dbContext,但它的状态是分离的。 EF可能希望我以不同于我的方式添加对象吗?我怀疑SimulationCollectionEntity中的属性可能会给我带来麻烦,但我是实体框架的新手,我不确定。我是否应该换一种不同的设计,而不是像this?
我使用链接的解决方案解决了这个问题,谢谢!我从userManager中删除了上下文,并简单地在每次请求时创建userManager。出于好奇,就我所知,所有的缓存都是通过上下文来完成的,你不想因为这个原因而试图坚持它们吗? – CalumMcCall 2014-10-02 10:46:30
这是一个原因,在很长的上下文环境中,您可以想象到上下文中内存中数据库中的所有内容,但dbContext是一个非常轻的权重对象,所以当您需要时无需旋转它并在完成后处置它。您可以放心,底层的sql连接将被释放并释放回池中。我也认为这会让你更多地考虑你的代码,并且将它结构化得更好一些,我见过的最慢的mvc视图涉及到一个ContextPerRequest和一个延迟加载的集合,导致了每个项目的数据库调用。 – 2014-10-02 17:48:45