使用 ASP.NET MVC 5 和 Entity Framework 6,我正在尝试将新记录 Package
保存到数据库中。我有以下模型实体:
User.cs(默认模板中的ApplicationUser
)
public class User : IdentityUser
{
private ICollection<Package> packages;
public User()
{
this.packages = new HashSet<Package>();
}
public virtual ICollection<Package> Packages
{
get { return this.packages; }
set { this.packages = value; }
}
...
}
Package.cs
public class Package
{
private ICollection<User> maintainers;
public Package()
{
this.maintainers = new HashSet<User>();
}
[Required]
public virtual ICollection<User> Maintainers
{
get
{
return this.maintainers;
}
set
{
this.maintainers = value;
}
}
...
}
我有以下 DbContext 类:
public class ApplicationDbContext : IdentityDbContext<User>, IApplicationDbContext
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public virtual IDbSet<Package> Packages { get; set; }
...
public static ApplicationDbContextCreate()
{
return new ApplicationDbContext();
}
}
我还有PackageService.cs(类似于服务模式):
public class PackagesService : IPackagesService
{
private readonly IRepository<Package> packages;
public PackagesService(IRepository<Package> packages)
{
this.packages = packages;
}
public Package Create(IList<User> maintainers)
{
var newPackage = new Package
{
Maintainers = maintainers
};
this.packages.Add(newPackage);
this.packages.SaveChanges();
return newPackage;
}
}
我还有 IRepository 作为 GenericRepository 的标准实现:source code here .
现在我遇到的问题是,当 Create()
方法被调用时,Entity Framework 抛出以下异常:
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code
Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
我知道问题是 Package
实体由两个不同的 DbContext 跟踪更改,但我在整个应用程序中使用相同的 ApplicationDbContext
。此外,这是我注入(inject)它的方式(使用 Ninject):
kernel.Bind<DbContext>().To<ApplicationDbContext>().InRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>));
kernel.Bind<IUserStore<User>>().To<UserStore<User>>().WithConstructorArgument("context", kernel.Get<DbContext>());
kernel.Bind<UserManager<User>>().ToSelf();
这是最让我困惑的部分。我不仅将上下文与 Ninject 绑定(bind),而且无论我在哪里使用 UserManager
,我都通过 Owin 实例获取它,该实例使用完全相同的 DbContext 的 Create() 静态方法创建它。那么怎么会有两个 DbContext 实例呢?
我花了一整天的时间对此进行调试,但我不明白为什么会这样。提前致谢。
最佳答案
我不确定问题是否出在 DI 绑定(bind),尤其是 Ninject,但我设法找到了解决方法。因为显然我有两个 DbContext 实例,所以我没有使用第一个实例中的记录,而是仅将多对多关系映射到主键。大致如下:
if (maintainerIds != null && maintainerIds.Count > 0)
{
foreach (string maintainerId in maintainerIds)
{
var maintainer = new User() { Id = maintainerId };
users.Attach(maintainer);
newPackage.Maintainers.Add(maintainer);
}
}
只要 ID 匹配,这基本上甚至不需要 DbContext。
关于c# - Entity Framework 和 ASP.NET Identity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35234144/