gpt4 book ai didi

c# - 找不到引用 Entity Framework 实体的对象

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:03 25 4
gpt4 key购买 nike

我遇到了 InvalidOperationException,因为“一个实体对象不能被 IEntityChangeTracker 的多个实例引用。”在 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;
}
}

有没有一种简单的方法可以查看给定对象可能附加到哪些上下文?我已经检查过 collectionEntity 是否附加到 _userManager,因为它有一个 dbContext,但它的状态是分离的。 EF 是否可能希望我以与我不同的方式添加对象?我怀疑 SimulationCollectionEntity 中的属性可能会给我带来麻烦,但我是 Entity Framework 的新手,我不确定。我是否应该采用不同的设计而不是像 this

最佳答案

您可能想要考虑一种类似工作单元的方法,其中一个上下文在多个存储库之间共享。此 post 的公认答案是一个很好的例子。我见过 ContextPerRequest 解决方案,例如您示例中的解决方案,但我从未对它们感到疯狂。理想情况下,您需要一个短暂的上下文来做一件事,比如添加一张发票和两个发票项目——一个单一的工作单元。然后您可以将整个操作包装在 TransactionScope 中并将其作为一个整体成功或失败。

关于c# - 找不到引用 Entity Framework 实体的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26146304/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com