【发布时间】:2016-02-05 21:50:30
【问题描述】:
使用 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 会抛出以下异常:
EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理
附加信息:一个实体对象不能被多个 IEntityChangeTracker 实例引用。
我知道问题在于 Package 实体由两个不同的 DbContexts 进行更改跟踪,但我在整个应用程序中使用相同的 ApplicationDbContext。此外,这是我注入它的方式(使用 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 绑定,而且无论在哪里使用,即UserManager,我都通过 Owin 实例获取它,该实例使用完全相同的 DbContext 的 Create() 静态方法创建它。那么怎么会有两个 DbContext 实例呢?
我花了一整天的时间来调试这个,我不明白为什么会这样。提前致谢。
【问题讨论】:
-
你的类定义说
ApplicationDbContext,但是在你的ninject配置kernel.Bind<DbContext>().To<LinuxPackagesDbContext>().InRequestScope();你能澄清一下吗 -
已修复,复制粘贴出错。
-
@arnaudoff 也许删除问题或在答案中写下问题所在
-
当您通过维护者
public Package Create(IList<User> maintainers)时,它是否可能来自另一个上下文?尝试注释掉Maintainers = maintainers看看是否是问题所在。至少这可以帮助你缩小范围 -
@b1tsh1ft,好吧,删除该行似乎可以解决问题,但这并不能解决问题。维护者来自
this.UserManager.Users,其中UserManager属性与创建新项目时出现的默认MVC 模板中来自ManageController.cs的属性完全相同,因此从Owin 管道获取上下文。
标签: c# asp.net .net asp.net-mvc entity-framework