错误'无法完成操作,因为已经处理了DbContext。'

时间:2018-03-29 17:05:15

标签: asp.net-mvc repository unit-of-work

我在asp.net MVC中使用通用存储库和工作单元。当我想访问控制器中的上下文时,我收到此错误: '操作无法完成,因为已经处理了DbContext。'

然而,当我评论这一行时: 'Database.SetInitializer(new MigrateDatabaseToLatestVersion());' 在Global.asax中,错误将得到解决。但是一旦我取消注释该行,错误仍然会发生。

这里是通用存储库:

public class GenericRepository<TEntity> where TEntity : class
{
    internal ZarinParse_Context context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(ZarinParse_Context context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
    {
        return dbSet.SqlQuery(query, parameters).ToList();
    }

    public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual TEntity GetByID(object id)
    {
        return dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Update(TEntity entity)
    {
        dbSet.Attach(entity);
        context.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entity)
    {
        if (context.Entry(entity).State == EntityState.Detached)
        {
            dbSet.Attach(entity);
        }
        dbSet.Remove(entity);
    }
}

和工作单位:

public class UnitOfWork : IDisposable
{
    private ZarinParse_Context context;
    private RoleRepository roleRepository;
    private UserRepository userRepository;
    private UserRoleRepository userRoleRepository;

    public UnitOfWork()
    {
        context = new ZarinParse_Context();
    }

    public RoleRepository RoleRepository
    {
        get
        {

            if (this.roleRepository == null)
            {
                this.roleRepository = new RoleRepository(context);
            }
            return roleRepository;
        }
    }

    public UserRepository UserRepository
    {
        get
        {

            if (this.userRepository == null)
            {
                this.userRepository = new UserRepository(context);
            }
            return userRepository;
        }
    }

    public UserRoleRepository UserRoleRepository
    {
        get
        {

            if (this.userRoleRepository == null)
            {
                this.userRoleRepository = new UserRoleRepository(context);
            }
            return userRoleRepository;
        }
    }

    public void Save()
    {
        context.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

RoleRepository类:

public class RoleRepository : GenericRepository<Role>
{
    public RoleRepository(ZarinParse_Context context)
        : base(context)
    {
    }
}

我的背景:

public class ZarinParse_Context : DbContext
{
    public IDbSet<User> Users { get; set; }
    public IDbSet<Role> Roles { get; set; }
    public IDbSet<UserRole> UserRoles { get; set; }
    public IDbSet<Product> Products { get; set; }
    public IDbSet<Tag> Tags { get; set; }
    public IDbSet<TagProduct> TagProducts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new UserConfig());
        modelBuilder.Configurations.Add(new RoleConfig());
        modelBuilder.Configurations.Add(new UserRoleConfig());
        modelBuilder.Configurations.Add(new ProductConfig());
        modelBuilder.Configurations.Add(new TagConfig());
        modelBuilder.Configurations.Add(new TagProductConfig());
    }
}

我的控制器:

public class HomeController : Controller
{
    UnitOfWork unitOfWork = new UnitOfWork();

    public ActionResult Index()
    {
        var model = new Role() { Name = "User" };
        unitOfWork.RoleRepository.Insert(model);
        unitOfWork.Save();

        return View();
    }

    protected override void Dispose(bool disposing)
    {
        unitOfWork.Dispose();
        base.Dispose(disposing);
    }
}

和Global.asax文件:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        Database.SetInitializer(new MigrateDatabaseToLatestVersion<ZarinParse_Context, Configuration>());
    }
}

和配置:

public class Configuration : DbMigrationsConfiguration<ZarinParse_Context>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;
        ContextKey = "ZarinParse.DomainClasses.Context.ZarinParse_Context";
    }

    protected override void Seed(ZarinParse_Context context)
    {
        InitializeAdmin(context: context,
                        roleName: "Admin",
                        userName: "soheil91141121@gmail.com",
                        password: "stb_91141121",
                        fullName: "سهیل تقی زاده بنگر",
                        mobileNumber: "09356336121",
                        newsEamilEnabled: true);
    }

    private void InitializeAdmin(ZarinParse_Context context, string roleName, string userName, string password, string fullName, bool newsEamilEnabled, string mobileNumber)
    {
        //Create Role Admin if it does not exist
        var roleExist = context.Roles.Any(p => p.Name == roleName);
        if (!roleExist)
        {
            var role = Role.Create();
            role.Name = roleName;

            context.Roles.Add(role);
            context.SaveChanges();
        }

        //Create User if it does not exist
        var userExist = context.Users.Any(p => p.UserName == userName);
        if (!userExist)
        {
            var user = User.Create();
            user.UserName = userName;
            user.Email = userName;
            user.Password = password.Encrypt();
            user.FullName = fullName;
            user.NewsEmailEnabled = newsEamilEnabled;
            user.MobileNumber = mobileNumber;

            context.Users.Add(user);
            context.SaveChanges();
        }

        //Create UserRole if it does not exist
        var role2 = context.Roles.Single(p => p.Name == roleName);
        var user2 = context.Users.Single(p => p.UserName == userName);
        var userRoleExist = context.UserRoles.Any(p => p.RoleId == role2.RoleId && p.UserId == user2.UserId);
        if (!userRoleExist)
        {
            var userRole = UserRole.Create();
            userRole.Role = role2;
            userRole.User = user2;

            context.UserRoles.Add(userRole);
            context.SaveChanges();
        }
        context.Dispose();
    }
}

1 个答案:

答案 0 :(得分:0)

InitializeAdmin的最后一行处理传递给方法的上下文。

只处理您创建的对象,因为您拥有对象的生命周期。

换句话说,不要处理你不拥有的物品。