【问题标题】:context.SaveChanges() not updating data in databasecontext.SaveChanges() 不更新数据库中的数据
【发布时间】:2017-08-15 11:01:47
【问题描述】:

我的 ApplictionDbContextClass 看起来像这样:-

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    //private static ApplicationDbContext _context;
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    public DbSet<Trip> Trips { get; set; }
    public DbSet<Place> Places { get; set; }
    public DbSet<UserTripDetail> UserTripDetails { get; set; }
    public DbSet<TripPicture> TripPictures { get; set; }
}

我的 TripPictureController 如下所示:-

    //private readonly ApplicationDbContext _db = new ApplicationDbContext();
    private readonly IUnitOfWork _unitOfWork;
    private readonly ITripPictureRepository _tripPictureRepository;

    public TripPicturesController(IUnitOfWork unitOfWork, ITripPictureRepository tripPictureRepository)
    {
        _unitOfWork = unitOfWork;
        _tripPictureRepository = tripPictureRepository;
    }

它还包含一个post Action:-

    [HttpPost]
    public ActionResult Create(TripPicture model, HttpPostedFileBase ImageData)
    {
        if (ImageData != null)
        {
            model.TripId = 1;
            model.Image = this.ConvertToBytes(ImageData);
        }
        _tripPictureRepository.Add(model);
        _unitOfWork.Commit();
        //_db.TripPictures.Add(model);
        //_db.SaveChanges();
        return View(model);
    }

当我点击发布请求时,模型不会被推送到数据库中。我在这里使用依赖注入。我的猜测是在某个地方创建了不同的上下文对象。我在启动类中看到了以下代码:-

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(**ApplicationDbContext.Create**);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);}

我的 unitOfWork 课程是:-

public class UnitOfWork : IUnitOfWork
{
    private DbContext _context;
    public UnitOfWork(DbContext dbContext)
    {
        _context = dbContext;
    }
    public void Commit()
    {
        _context.SaveChanges();
    }
}

我的存储库类是:-

public class Repository<T> : IRepository<T> where T : class
{
    protected DbSet<T> _dbSet;

    public Repository(DbContext context)
    {
        _dbSet = context.Set<T>();
    }

    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }
}

当我不使用 unitOfWork 时,对象被保存。有什么问题!?

【问题讨论】:

  • 请提供repositoryAdd方法和unitOfWorkCommit方法
  • 我添加了 iven unitOfWork 和 Repository 类方法
  • “我的猜测是在某个地方创建了不同的上下文对象。”我也是这么想。您可以通过在存储库和工作单元的构造函数中设置断点来轻松验证这一点。然后您可以调用.GetHashCode(),如果结果不同,那么对象本身就是不同的(据我所知,DbContext 不会覆盖GetHashCode)。
  • 请告诉我们IUnitOfWorkIRepository是如何注册到你的IoC容器的。
  • 感谢@Balázs,您的建议很有用。

标签: c# entity-framework asp.net-mvc-4 dependency-injection repository-pattern


【解决方案1】:

您正在错误地实施工作单元模式。

您正在向_tripPictureRepository 实例 DbContext 添加一个项目,并在 _unitOfWork 实例上调用 _unitOfWork.Commit(),该实例具有另一个不知道添加的项目的 DbContext 实例(_unitOfWork 的 DbContext 不跟踪项目)这意味着它什么也没节省。

工作单元的正确实现是您的存储库应该作为属性公开,DbContext 注入到您的工作单元类和存储库的DbSet&lt;T&gt; 将从DbContext 填充,如下所示:

public class UnitOfWork : IUnitOfWork
{
    private DbContext _context;

    public ITripPictureRepository TripsRepository{ get; }

    public UnitOfWork(DbContext dbContext)
    {
        _context = dbContext;
        Trips = new Repository<Trip>(_context.Trips)
    }

    public void Commit()
    {
        _context.SaveChanges();
    }
}

然后在你的控制器中注入一个 IUnitOfWork 实例:

private readonly IUnitOfWork _unitOfWork;

public TripPicturesController(IUnitOfWork unitOfWork)
{
    _unitOfWork = unitOfWork;
    _tripPictureRepository = tripPictureRepository;
}

现在使用 _unitOfWork 实例来执行您的 CRUD 操作:

[HttpPost]
public ActionResult Create(TripPicture model, HttpPostedFileBase ImageData)
{
    if (ImageData != null)
    {
        model.TripId = 1;
        model.Image = this.ConvertToBytes(ImageData);
    }

    _unitOfWork.TripsRepository.Add(model);
    _unitOfWork.Commit();

    return View(model);
}

您可以通过Microsoft Docs page了解更多关于存储库和工作单元模式的信息。

【讨论】:

  • Buti 在这里使用 ninject 依赖注入。它不应该在构造函数中需要的任何地方注入相同的 DbContext 对象吗?
  • 您指出的方式是实现存储库模式的一种方式,即不使用依赖注入。我的 unitOfWork 实现没有错,因为我使用依赖注入,并且它能够在任何需要的地方注入相同的对象,因此我的存储库和 unitOfWork 实际上是在同一个 DbContext 对象上工作。
【解决方案2】:

我发现了问题。每当由 ninject 生成时,我的 DbContextObjects 都是不同的。在我的 ninject 文件中,我在内核中注册服务如下:-

kernel.Bind<DbContext>().To<ApplicationDbContext>();

这默认使用瞬态范围,即每次需要时都会创建新对象。 因此我需要将其更改为以下内容:-

kernel.Bind<DbContext>().To<ApplicationDbContext>().InRequestScope();

请求的范围意味着 - 只会创建该类型的单个实例,并且为每个后续请求返回相同的实例。

更多信息可以在这里找到:- https://github.com/ninject/ninject/wiki/Object-Scopes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2016-01-08
    • 2019-06-24
    相关资源
    最近更新 更多