Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在我的存储库类和控制器类之间协调以使用相同的上下文对象_C#_Asp.net_Asp.net Mvc_Entity Framework 6_Unit Of Work - Fatal编程技术网

C# 在我的存储库类和控制器类之间协调以使用相同的上下文对象

C# 在我的存储库类和控制器类之间协调以使用相同的上下文对象,c#,asp.net,asp.net-mvc,entity-framework-6,unit-of-work,C#,Asp.net,Asp.net Mvc,Entity Framework 6,Unit Of Work,我正在开发一个asp.net mvc web应用程序。现在,我创建了多个存储库类,例如,我有以下抽象存储库类:- public interface ISkillRepository : IDisposable {//code goes here.. & 以及模型存储库:- public class SkillRepository : ISkillRepository , IDisposable { private SkillManagementEntitie

我正在开发一个asp.net mvc web应用程序。现在,我创建了多个存储库类,例如,我有以下抽象存储库类:-

public interface ISkillRepository : IDisposable
{//code goes here..
&

以及模型存储库:-

public class SkillRepository :  ISkillRepository , IDisposable
                {
 private SkillManagementEntities context = new SkillManagementEntities();
    //code goes here
&

现在,在y控制器内,我正在初始化并创建回购协议,如下所示:-

 public class SkillController : Controller
    {

        private ISkillRepository skillRepository;


      public SkillController() : this(new SkillRepository()) {}

      public SkillController(ISkillRepository repository)
      {
          skillRepository = repository;
      }
   public class SecurityRoleController : Controller
    {

        private UnitOfWork unitOfWork = new UnitOfWork();

        public async Task<ActionResult> Index(string filter = null, int page = 1, int pageSize = 20, string sort = "Name", string sortdir = "ASC")
        {

            try
            {
                var records = new PagedList<SecurityRole>();
                ViewBag.filter = filter;
                records.Content = await unitOfWork.SecurityRoleRepository.GetSecurityRoleForGrid(filter, page, pageSize, sort, sortdir).ToListAsync();
   public class SkillRepository :  ISkillRepository , IDisposable
            {
                private SkillManagementEntities context ;

                private IStaffRepository staffrepo = (IStaffRepository)DependencyResolver.Current.GetService(typeof(IStaffRepository));
                public SkillRepository(SkillManagementEntities context)
                {
                  this.context = context;
                }
 public class StaffController : Controller
    {
        //private SkillManagementEntities db = new SkillManagementEntities();

        UnitOfWork unitofwork = new UnitOfWork();




    public async Task<ActionResult> AutoComplete(string term)
      {

          var staff = await unitofwork.StaffRepository.GetAllActiveStaff(term).Select(a => new { label = a.SamAccUserName }).ToListAsync();

          return Json(staff, JsonRequestBehavior.AllowGet);
但目前我的应用程序中出现以下错误:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
问题是我需要在回购协议和控制器之间传递相同的上下文。因此,任何人都可以就此发表意见:-

  • 如何在一个模型repo中使用相同的上下文类引用另一个repo。例如,在员工库中引用技能库

  • 如何在控制器类中引用多个repo,但同时在它们之间传递相同的上下文对象,因此如果我发出save(),它将在一个事务中封装所有语句。例如,insie my skillController使用相同的上下文对象引用skill和staff repo

  • 谢谢

    编辑 我创建了以下工作单元类:-

     public class UnitOfWork : IDisposable
        {
            private SkillManagementEntities context = new SkillManagementEntities();
            private SkillRepository skillRepository;
            private StaffRepository staffRepository;
            private SecurityRoleRepository securityroleRepository;
            public SkillRepository SkillRepository
            {
                get
                {
    
                    if (this.skillRepository == null)
                    {
                        this.skillRepository = new SkillRepository(context);
                    }
                    return skillRepository;
                }
            }
    
            public StaffRepository StaffRepository
            {
                get
                {
    
                    if (this.staffRepository == null)
                    {
                        this.staffRepository = new StaffRepository(context);
                    }
                    return staffRepository;
                }
            }
            public SecurityRoleRepository SecurityRoleRepository
            {
                get
                {
    
                    if (this.staffRepository == null)
                    {
                        this.staffRepository = new SecurityRoleRepository(context);
                    }
                    return securityroleRepository;
                }
            }
            public async Task Save()
            {
                await context.SaveChangesAsync();
            }
    
            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);
            }
        }
    }
    
    然后在回购协议中,我做了以下几点:-

     public class SecurityRoleRepository :  ISecurityRoleRepository , IDisposable
            {
                private SkillManagementEntities context;// = new SkillManagementEntities();
    
                public SecurityRoleRepository(SkillManagementEntities context)
                {
                  this.context = context;
    
    在控制器类上,我将引用UnitOfWork,如下所示:-

     public class SkillController : Controller
        {
    
            private ISkillRepository skillRepository;
    
    
          public SkillController() : this(new SkillRepository()) {}
    
          public SkillController(ISkillRepository repository)
          {
              skillRepository = repository;
          }
    
       public class SecurityRoleController : Controller
        {
    
            private UnitOfWork unitOfWork = new UnitOfWork();
    
            public async Task<ActionResult> Index(string filter = null, int page = 1, int pageSize = 20, string sort = "Name", string sortdir = "ASC")
            {
    
                try
                {
                    var records = new PagedList<SecurityRole>();
                    ViewBag.filter = filter;
                    records.Content = await unitOfWork.SecurityRoleRepository.GetSecurityRoleForGrid(filter, page, pageSize, sort, sortdir).ToListAsync();
    
       public class SkillRepository :  ISkillRepository , IDisposable
                {
                    private SkillManagementEntities context ;
    
                    private IStaffRepository staffrepo = (IStaffRepository)DependencyResolver.Current.GetService(typeof(IStaffRepository));
                    public SkillRepository(SkillManagementEntities context)
                    {
                      this.context = context;
                    }
    
     public class StaffController : Controller
        {
            //private SkillManagementEntities db = new SkillManagementEntities();
    
            UnitOfWork unitofwork = new UnitOfWork();
    
    
    
    
        public async Task<ActionResult> AutoComplete(string term)
          {
    
              var staff = await unitofwork.StaffRepository.GetAllActiveStaff(term).Select(a => new { label = a.SamAccUserName }).ToListAsync();
    
              return Json(staff, JsonRequestBehavior.AllowGet);
    
    二,。然后,我创建了以下依赖项类:-

        public class YourDependencyResolverClass : IDependencyResolver
    {
        private IKernel kernel;
    
        public YourDependencyResolverClass()
        {
            kernel = new StandardKernel();
            AddBindings();
        }
    
        public object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }
    
    
        private void AddBindings()
        {
            kernel.Bind<ISkillRepository>().To<SkillRepository>();
            kernel.Bind<IStaffRepository>().To<StaffRepository>();
            kernel.Bind<ISecurityRoleRepository>().To<SecurityRoleRepository>();
            kernel.Bind<ICustomerRepository>().To<CustomerRepository>();
            kernel.Bind<ISkillVersionHistoryRepository>().To<SkillVersionHistoryRepository>();
         }
    }
    }
    
    最后,在action方法中,我将调用Uiteofwork类,如下所示:-

     public class SkillController : Controller
        {
    
            private ISkillRepository skillRepository;
    
    
          public SkillController() : this(new SkillRepository()) {}
    
          public SkillController(ISkillRepository repository)
          {
              skillRepository = repository;
          }
    
       public class SecurityRoleController : Controller
        {
    
            private UnitOfWork unitOfWork = new UnitOfWork();
    
            public async Task<ActionResult> Index(string filter = null, int page = 1, int pageSize = 20, string sort = "Name", string sortdir = "ASC")
            {
    
                try
                {
                    var records = new PagedList<SecurityRole>();
                    ViewBag.filter = filter;
                    records.Content = await unitOfWork.SecurityRoleRepository.GetSecurityRoleForGrid(filter, page, pageSize, sort, sortdir).ToListAsync();
    
       public class SkillRepository :  ISkillRepository , IDisposable
                {
                    private SkillManagementEntities context ;
    
                    private IStaffRepository staffrepo = (IStaffRepository)DependencyResolver.Current.GetService(typeof(IStaffRepository));
                    public SkillRepository(SkillManagementEntities context)
                    {
                      this.context = context;
                    }
    
     public class StaffController : Controller
        {
            //private SkillManagementEntities db = new SkillManagementEntities();
    
            UnitOfWork unitofwork = new UnitOfWork();
    
    
    
    
        public async Task<ActionResult> AutoComplete(string term)
          {
    
              var staff = await unitofwork.StaffRepository.GetAllActiveStaff(term).Select(a => new { label = a.SamAccUserName }).ToListAsync();
    
              return Json(staff, JsonRequestBehavior.AllowGet);
    

    那么,您能同意我使用UniteWork和DI的方法是否能保证我的所有语句都会在单个DB事务中扭曲吗?thnaks?

    我们通过使用HttpContext共享一个范围为请求的单例上下文来处理这个问题:

        public MyContext GetContext()
        {
            if (System.Web.HttpContext.Current.Items["MyScopedContext"] == null)
            {
                System.Web.HttpContext.Current.Items["MyScopedContext"] = new MyContext();
            }
    
            return (MyContext)System.Web.HttpContext.Current.Items["MyScopedContext"];
        }
    
    上下文对象(存储库)本身实际上包含一个工作单元。我在上面添加的代码只提供了一种方法,可以跨一个请求中运行的所有代码共享一个存储库。如果您的存储库类是在web应用程序的范围内定义的,则只需将SkillManagementEntities()的直接实例化替换为对GetContext()方法的调用即可


    另一方面,如果存储库是在异构应用程序共享的层中定义的,则可能需要从factory对象获取上下文,以便根据需要注入。无论哪种方式,每个存储库创建一个新的上下文对象都会导致您的问题。

    我们通过使用HttpContext共享一个范围为请求的单例上下文来处理这个问题:

        public MyContext GetContext()
        {
            if (System.Web.HttpContext.Current.Items["MyScopedContext"] == null)
            {
                System.Web.HttpContext.Current.Items["MyScopedContext"] = new MyContext();
            }
    
            return (MyContext)System.Web.HttpContext.Current.Items["MyScopedContext"];
        }
    
    上下文对象(存储库)本身实际上包含一个工作单元。我在上面添加的代码只提供了一种方法,可以跨一个请求中运行的所有代码共享一个存储库。如果您的存储库类是在web应用程序的范围内定义的,则只需将SkillManagementEntities()的直接实例化替换为对GetContext()方法的调用即可


    另一方面,如果存储库是在异构应用程序共享的层中定义的,则可能需要从factory对象获取上下文,以便根据需要注入。无论哪种方式,每个存储库创建一个新的上下文对象都会导致您的问题。

    我们通过使用HttpContext共享一个范围为请求的单例上下文来处理这个问题:

        public MyContext GetContext()
        {
            if (System.Web.HttpContext.Current.Items["MyScopedContext"] == null)
            {
                System.Web.HttpContext.Current.Items["MyScopedContext"] = new MyContext();
            }
    
            return (MyContext)System.Web.HttpContext.Current.Items["MyScopedContext"];
        }
    
    上下文对象(存储库)本身实际上包含一个工作单元。我在上面添加的代码只提供了一种方法,可以跨一个请求中运行的所有代码共享一个存储库。如果您的存储库类是在web应用程序的范围内定义的,则只需将SkillManagementEntities()的直接实例化替换为对GetContext()方法的调用即可


    另一方面,如果存储库是在异构应用程序共享的层中定义的,则可能需要从factory对象获取上下文,以便根据需要注入。无论哪种方式,每个存储库创建一个新的上下文对象都会导致您的问题。

    我们通过使用HttpContext共享一个范围为请求的单例上下文来处理这个问题:

        public MyContext GetContext()
        {
            if (System.Web.HttpContext.Current.Items["MyScopedContext"] == null)
            {
                System.Web.HttpContext.Current.Items["MyScopedContext"] = new MyContext();
            }
    
            return (MyContext)System.Web.HttpContext.Current.Items["MyScopedContext"];
        }
    
    上下文对象(存储库)本身实际上包含一个工作单元。我在上面添加的代码只提供了一种方法,可以跨一个请求中运行的所有代码共享一个存储库。如果您的存储库类是在web应用程序的范围内定义的,则只需将SkillManagementEntities()的直接实例化替换为对GetContext()方法的调用即可


    另一方面,如果存储库是在异构应用程序共享的层中定义的,则可能需要从factory对象获取上下文,以便根据需要注入。无论如何,每个存储库创建一个新的上下文对象都是导致问题的原因。

    不是答案:这个“使用DI”建议回答了一个稍微不同的问题-OP正在寻找“工作单元”模式-而基本情况(工作单元的生命周期与请求/控制器的生命周期匹配)可以很容易地用任何DI框架解决,管理多个工作单元或具有较长生命周期的工作单元要困难得多,而专用的“工作单元工厂”(UnitofWorkFactory)可能是解决方案


    通常,当您使用接口/存储库和构造函数依赖项注入时,您有一些依赖项注入框架。您正在使用的解决方案很可能已经提供了“每个HTTP请求”的解决方案,或者允许轻松添加一个解决方案

    也就是说,如果您使用Unity,则有一个
    PerRequestLifetime
    lifetime管理器,它可以对同一接口/对象执行所有
    .Resolve
    调用,以返回给定请求的同一实例。请参阅MSDN文章中的更多信息

    近似样本:

    container.RegisterType<ISkillRepository, SkillRepository>();
    container.RegisterType<IOtherRepository, OtherRepository>();
    container.RegisterType<TheContext, TheContext>(new PerRequestLifetime());
    
    container.RegisterType();
    container.RegisterType();
    RegisterType(新PerRequestLifetime());
    
    通过这样的注册,并假设您已将ASP.NETMVC配置为在创建控制器时使用Unity解析类型,它将获得必要的依赖项(新实例)