实体框架和ASP.NET标识

时间:2016-02-05 21:50:31

标签: c# asp.net .net asp.net-mvc entity-framework

使用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实例?

我花了整整一天调试这个,我无法理解为什么会这样。提前谢谢。

1 个答案:

答案 0 :(得分:0)

我不确定问题是DI绑定和Ninject特别是,但我设法找到了解决方法。因为显然我有两个DbContext实例,而不是使用第一个的记录,我只用主键映射了多对多关系。以下内容:

{{1}}

只要ids匹配,这基本上甚至不需要DbContext。