繁体   English   中英

实体框架和ASP.NET标识

[英]Entity framework and ASP.NET Identity

使用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: 源代码

现在我遇到的问题是,当调用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实例呢?

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

我不确定问题是DI绑定和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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM