C# Ninject:entity对象不能被多个IEntityChangeTracker实例引用

C# Ninject:entity对象不能被多个IEntityChangeTracker实例引用,c#,asp.net-mvc,ninject,ninject.web.mvc,C#,Asp.net Mvc,Ninject,Ninject.web.mvc,我开始在我的MVC5代码第一个应用程序中使用Ninject。这是我的NinjectWebCommon.cs: private static IKernel CreateKernel() { var kernel = new StandardKernel(); try { kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new B

我开始在我的MVC5代码第一个应用程序中使用Ninject。这是我的NinjectWebCommon.cs:

private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            kernel.Bind<CMSContext>()
                .ToSelf()
                //.InSingletonScope();
                .InRequestScope();

            kernel.Bind<IExecutiveRepository>()
                .To<ExecutiveRepository>();

            kernel.Bind<IExecutiveSectionRepository>()
                .To<ExecutiveSectionRepository>();

            kernel.Bind<IExecutiveSectionMappingRepository>()
                .To<ExecutiveSectionMappingRepository>();

            kernel.Bind<IUserRepository>()
                .To<UserRepository>();

            kernel.Bind<IContentRepository>()
                .To<ContentRepository>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }
private静态IKernel CreateKernel()
{
var kernel=新的标准内核();
尝试
{
kernel.Bind().ToMethod(ctx=>()=>newbootstrapper().kernel);
kernel.Bind().To();
kernel.Bind()
.ToSelf()
//.InSingletonScope();
.InRequestScope();
kernel.Bind()
.To();
kernel.Bind()
.To();
kernel.Bind()
.To();
kernel.Bind()
.To();
kernel.Bind()
.To();
注册服务(内核);
返回内核;
}
接住
{
Dispose();
投
}
}
我尝试了.InSingletonScope()和.InRequestScope(),但仍然得到了“entity对象不能被多个IEntityChangeTracker实例引用”错误。 这是我的界面:

    public interface IExecutiveRepository : IDisposable
{
    IEnumerable<Executive> GetExecutives();
    Executive GetExecutiveById(int executiveId);
    void InsertExecutive(Executive executive);
    void UpdateExecutive(Executive executive);
    void DeleteExecutive(int executiveId);
    void Save();
}
公共接口IEExecutiveRepository:IDisposable
{
IEnumerable getExecutions();
执行GetExecutiveById(int-executiveId);
无效插入执行(执行);
无效更新执行(执行);
无效删除执行(int executiveId);
作废保存();
}
这是我的混凝土:

 public class ExecutiveRepository : IExecutiveRepository, IDisposable
{
    private CMSContext context;

    public ExecutiveRepository(CMSContext context)
    {
        this.context = context;
    }

    public IEnumerable<Executive> GetExecutives()
    {
        return context.Executives.ToList();
    }

    public Executive GetExecutiveById(int id)
    {
        return context.Executives.Find(id);
    }

    public void InsertExecutive(Executive executive)
    {
        context.Executives.Add(executive);
    }

    public void DeleteExecutive(int executiveId)
    {
        Executive executive = context.Executives.Find(executiveId);
        context.Executives.Remove(executive);
    }

    public void UpdateExecutive(Executive executive)
    {
        context.Entry(executive).State = EntityState.Modified;
    }

    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);
    }
}
公共类ExecutiveRepository:IEExecutiveRepository,IDisposable
{
私有CMSContext上下文;
公共行政存储(CMSContext上下文)
{
this.context=上下文;
}
公共IEnumerable getExecutions()
{
返回context.Executives.ToList();
}
公共执行GetExecutiveById(int id)
{
返回context.Executives.Find(id);
}
公共无效插入执行(执行)
{
context.Executives.Add(executive);
}
public void delete executive(int executiveId)
{
Executive=context.executies.Find(executiveId);
context.executive.Remove(executive);
}
公共无效更新执行(执行)
{
context.Entry(executive).State=EntityState.Modified;
}
公共作废保存()
{
SaveChanges();
}
私有布尔=假;
受保护的虚拟void Dispose(bool disposing)
{
如果(!this.disposed)
{
如果(处置)
{
context.Dispose();
}
}
这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}
以下是控制器(顶部相关部分):

公共类ExecutiveController:控制器
{
私人执行代理;
专用IUserRepository用户存储库;
专用IExecutiveSectionRepository executiveSectionRepository;
专用IExecutiveSectionMappingRepository executiveSectionMappingRepository;
私有IContentResposition内容存储库;
private Ninject.IKernel_kernel=新标准内核();
//[注入]
公共执行控制器()
{
executiveRepository=_kernel.Get();
userRepository=_kernel.Get();
executiveSectionRepository=_kernel.Get();
executiveSectionMappingRepository=_kernel.Get();
contentRepository=_kernel.Get();
}
...
我不确定我做错了什么,但在添加新的“高管”后,它会爆炸……我确实理解它试图使用不同的上下文,这就是问题所在,但我不确定如何解决它。显然,NinjectWebCommon.cs类中的行:

 kernel.Bind<CMSContext>()
                .ToSelf()
                //.InSingletonScope();
                .InRequestScope();
kernel.Bind()
.ToSelf()
//.InSingletonScope();
.InRequestScope();
应该是修复的,但不是。。。
有什么想法/建议吗?

这可能无法回答问题。但我倾向于使用EF提供的
IDbContextFactory
,并执行以下操作:

public interface IDefaultContextFactory : IDbContextFactory<CMSContext> {}

public class DefaultContextFactory : IDefaultContextFactory 
{
    private readonly Lazy<CMSContext> lazyContext = new Lazy<CMSContext>(() => new CMSContext());

    public CMSContext Create() 
    {
        return lazyContext.Value;
    }
}
public class ExecutiveRepository : IExecutiveRepository, IDisposable
{
    private readonly CMSContext context;

    public ExecutiveRepository(IDefaultContextFactory contextFactory)
    {
        this.context = contextFactory.Create();
    }
}

我相信BatteryBackupUnit是正确的,我也会考虑使用上面的模式来解决这个问题。

< P>这也许不能回答这个问题。但是我倾向于使用<代码> IDbContextFactory <代码>,EF给你提供这样的事情:

public interface IDefaultContextFactory : IDbContextFactory<CMSContext> {}

public class DefaultContextFactory : IDefaultContextFactory 
{
    private readonly Lazy<CMSContext> lazyContext = new Lazy<CMSContext>(() => new CMSContext());

    public CMSContext Create() 
    {
        return lazyContext.Value;
    }
}
public class ExecutiveRepository : IExecutiveRepository, IDisposable
{
    private readonly CMSContext context;

    public ExecutiveRepository(IDefaultContextFactory contextFactory)
    {
        this.context = contextFactory.Create();
    }
}

我相信“BatteryBackupUnit是正确的,我也会考虑使用上面的模式来实现上下文。

< p>您正在创建每个控制器的内核。

InRequestScope
只确保每个内核每个请求有一个实例

因此,您需要调整内核设置,以便每个web应用程序只有一个内核。请参阅:


    • 您正在为每个控制器创建一个内核

      InRequestScope
      只确保每个内核每个请求有一个实例

      因此,您需要调整内核设置,以便每个web应用程序只有一个内核。请参阅:


      如果尚未使用,则应该使用NUGET package
      Ninject.Web.Mvc
      。这将配置您的应用程序准备好使用Ninject,而不是绑定。从我在
      CreateKernel()
      方法中看到的情况来看,您似乎已经相当熟悉绑定方面的内容

      一旦绑定到位,就不应该在控制器中创建内核,这是因为
      Ninject.Web.Mvc
      库将Ninject配置为在后台为您创建控制器。因此,添加到控制器中的任何依赖项都应该自动解决

      因此,您可以使用构造函数注入来解决依赖关系:

      public class ExecutiveController : Controller
      {
          private IExecutiveRepository ExecutiveRepository;
          private IUserRepository UserRepository;
          private IExecutiveSectionRepository ExecutiveSectionRepository;
          private IExecutiveSectionMappingRepository ExecutiveSectionMappingRepository;
          private IContentRepository ContentRepository;
      
          public ExecutiveController(
               IExecutiveRepository executiveRepository,
               IUserRepository userRepository,
               IExecutiveSectionRepository executiveSectionRepository,
               IExecutiveSectionMappingRepository executiveSectionMappingRepository,
               IContentRepository contentRepository)
          {
      
               // Set the field values
               this.ExecutiveRepository = executiveRepository,
               this.UserRepository = userRepository,
               this.ExecutiveSectionRepository = executiveSectionRepository,
               this.ExecutiveSectionMappingRepository = executiveSectionMappingRepository,
               this.ContentRepository = contentRepository;
          }
      
          public ActionResult Index(int id)
          {
              // Use one of your dependencies...
              var executive = this.executiveRepository.GetExecutiveById(id);
          }
      }
      
      或者您可以使用具有相同效果的
      [Inject]
      属性:

      public class ExecutiveController : Controller
      {
          [Inject]
          public IExecutiveRepository executiveRepository { get; set; }
      
          [Inject]
          public IUserRepository userRepository { get; set; }
      
          [Inject]
          public IExecutiveSectionRepository executiveSectionRepository { get; set; }
      
          [Inject]
          public IExecutiveSectionMappingRepository executiveSectionMappingRepository { get; set; }
      
          [Inject]
          public IContentRepository contentRepository { get; set; }
      
          public ExecutiveController()
          {
      
          }
      
          public ActionResult Index(int id)
          {
              // Use one of your dependencies...
              var executive = this.executiveRepository.GetExecutiveById(id);
          }
      }
      

      如果尚未使用,则应使用NUGET软件包
      Ninject.Web.Mvc
      。这将配置应用程序以准备使用Ninjec