c# ASP.. NET MVC代码优先不保存更改

本文关键字:保存更改 代码 ASP NET MVC | 更新日期: 2023-09-27 18:17:06

我有一个非常简单的模型:

public class Item : DbEntity
{
    public string Name {get;set;}
    public int Quantity {get;set;}
    public virtual Category Category {get;set;}
}
public class Category : DbEntity
{
    public string Name {get;set;}
}

我使用下面的方法来保存和提交更改到数据库:

public void SaveEntity<TEntity>(TEntity entity) where TEntity : DbEntity
{
    if (entity.Id.Equals(Guid.Empty))
        _context.Set<TEntity>().Add(entity);
    else
        _context.Entry(entity).State = System.Data.EntityState.Modified;
    _context.SaveChanges();
}
public void DeleteEntity<TEntity>(TEntity entity) where TEntity : DbEntity
{
     _context.Set<TEntity>().Remove(entity);
     _context.SaveChanges();
}

这些保存和删除方法驻留在存储库中,这个存储库是注入的,所以它应该在整个应用程序生命周期中保持恒定状态。这是一种久经考验的方法,对我来说一直很有效。由于某些原因,当我这样做的时候:

[HttpPost]
public ActionResult Edit(MenuItemViewModel vm)
{
    if (ModelState.IsValid)
    {
        // TODO: Add ViewModel Logic
        vm.MenuItem.Category = _repository.Categories.FirstOrDefault(x => x.Id.Equals(vm.SelectedCategory));
    try
    {
        // TODO: Add Save Logic
            _repository.SaveEntity(vm.MenuItem);
            TempData["success"] = true;
            TempData["message"] = String.Format("Saved {0} Successfully", vm.MenuItem.Description);
    }
    catch (Exception ex)
    {
             TempData["error"] = true;
             TempData["message"] = "Error Occured";
    }
    return _redirectTo;
    }
    return View("Shape", vm);
}

视图部分很简单,只是NameQuantity的一些字段,Category是一个Drop Down框,包含所有类别名称为Text和id为Value,这被发布回存储库所在的服务器,并收集新的Category并将其分配给实体。

由于某种原因,这只是不提交任何更改到数据库,断点前后,当我打破后,我检查了数据库,它没有改变!

有谁能看出阻止它更新的愚蠢的小错误吗?

编辑

只是阅读这个StackOverflow Post,我拾取了它所说的部分,你先附加它然后编辑它,因为当attach被调用时,你用Unchanged状态调用它,然后当你修改它时,当你调用SaveChanges()时,更改将被保存。

这和它有关系吗?!

更新
好吧,一些有趣的消息,我通过SaveEntity方法,在我通过SaveChanges()后,我再次检查上下文,它显示它已被更新?!我重定向到另一个控制器和操作会影响结果或表修改吗?我不认为SaveEntity方法有问题!!

最新更新

我改变了Item的模型,并简单地添加了public Guid CategoryId {get;set;}行,这简单地改变了Category以打开Cascade On Delete。现在我得到这个错误,当我尝试和SaveChanges:

发生了引用完整性约束冲突:定义引用约束的属性值在关系中的主体对象和从属对象之间不一致。

c# ASP.. NET MVC代码优先不保存更改

因此,为了解决这个问题,我将Item实体更改为:

public class Item : DbEntity
{
    public string Name {get;set;}
    public int Quantity {get;set;}
    public Guid? CategoryId {get;set;}
    public virtual Category Category {get;set;}
}

这基本上使更改Category变得更容易和更快,因为您不必再次调用数据库。?Cascade Delete设置为No Action,这样当您删除Item时,它就不会恼人地关闭并删除相关的Categories

我仍然不知道为什么原来的方式不起作用,它在过去已经做过了,它曾经否定必须把public Guid? CategoryId {get;set;},因为它会设置可空属性,并且已经创建了一个Category_Id字段。但是,嘿嗬,这就是它想要的方式,然后我会打球!!

在SaveEntity中,如果Id不等于Guid。如果为空,则不将项附加到上下文,只是将State设置为Modified。试一试:

public void SaveEntity<TEntity>(TEntity entity) where TEntity : DbEntity
{
    if (entity.Id.Equals(Guid.Empty))
    {
        _context.Set<TEntity>().Add(entity); // Automatically sets state to Added
    }
    else 
    {
        _context.Set<TEntity>().Attach(entity);
        _context.Entry(entity).State = System.Data.EntityState.Modified;
    }
    _context.SaveChanges();
}

此外,对于DeleteEntity,尝试附加和删除:

public void DeleteEntity<TEntity>(TEntity entity) where TEntity : DbEntity
{
    _context.Set<TEntity>().Attach(entity); // Attaches entity with state Unchanged
    _context.Set<TEntity>().Remove(entity); // Changes entity state to Deleted
    _context.SaveChanges();
}

关键是在一个断开连接的环境中,如ASP。. NET中,从post返回的模型没有附加到上下文,因此需要在处理它之前重新附加。

作为测试,在调用SaveChanges之前,检查现有代码中实体的状态,它很可能是Unchanged,这意味着不会对其采取任何操作。