我正在将此模板用于我的项目
public interface IUnitOfWork
{
IDbSet<TEntity> Set<TEntity>() where TEntity : class;
int SaveChanges();
void RejectChanges();
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
}
实现:
public class BookStoreDbContext : DbContext, IUnitOfWork
{
public DbSet<Categori> Categoris { get; set; }
public new DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class
{
return base.Entry(entity);
}
public override int SaveChanges()
{
return base.SaveChanges();
}
的Controler:
public class CategoriController : Controller
{
private IUnitOfWork _uw;
private ICategoriService _categoriService;
public CategoriController(IUnitOfWork uw,ICategoriService categoriservice )
{
_uw = uw;
_categoriService = categoriservice;
}
public ActionResult Edit(int id = 0)
{
var categori = _categoriService.Find(i => i.Id == id);
if (categori == null)
{
return HttpNotFound();
}
return View(categori);
}
[HttpPost]
public ActionResult Edit(Categori categori)
{
if (ModelState.IsValid)
{
_uw.Entry(categori).State = EntityState.Modified;
_uw.SaveChanges();
}
return View(categori);
}
}
存储库或服务层:
public interface IGenericService<T> : IDisposable where T : class
{
void Add(T entity);
void Delete(T entity);
T Find(Func<T, bool> predicate);
IList<T> GetAll();
IList<T> GetAll(Func<T, bool> predicate);
}
public interface ICategoriService : IGenericService<DomainClasses.Models.Categori>
{
}
impliment repository:
public class EfGenericService<TEntity> : IGenericService<TEntity> where TEntity : class
{
protected IUnitOfWork _uow;
protected IDbSet<TEntity> _tEntities;
public EfGenericService(IUnitOfWork uow)
{
_uow = uow;
_tEntities = _uow.Set<TEntity>();
}
public virtual void Add(TEntity entity)
{
_tEntities.Add(entity);
}
public void Delete(TEntity entity)
{
_tEntities.Remove(entity);
}
public TEntity Find(Func<TEntity, bool> predicate)
{
return _tEntities.Where(predicate).FirstOrDefault();
}
public IList<TEntity> GetAll()
{
return _tEntities.ToList();
}
public IList<TEntity> GetAll(Func<TEntity, bool> predicate)
{
return _tEntities.Where(predicate).ToList();
}
public class EfCategoriService : EfGenericService<Categori>,ICategoriService
{
public EfCategoriService(IUnitOfWork uow)
: base(uow)
{
}
}
Global.asax
private static void InitStructureMap()
{
ObjectFactory.Initialize(
x =>
{
x.For<IUnitOfWork>().HttpContextScoped().Use(() => new BookStoreDbContext());
x.ForRequestedType<ServiceLayer.Interfaces.ICategoriService>()
.TheDefaultIsConcreteType<EfCategoriService>();
}
但是我在更新实体时遇到了这个错误:
存储更新,插入或删除语句会影响意外的行数(0)。自实体加载后,实体可能已被修改或删除。刷新ObjectStateManager条目
请帮我解决此错误?
答案 0 :(得分:1)
您的摘要中唯一相关的行是:
_uw.Entry(categori).State = EntityState.Modified;
_uw.SaveChanges();
现在,看看你得到的例外:
存储更新,插入或删除语句会影响意外 行数(0)。自那以后,实体可能已被修改或删除 实体已加载。
Modified
插入实体?否。是否更新实体?是
EF尝试更新的实体是否已已删除?好吧,也许吧。怎么检查?删除实体时,数据库必须知道密钥才能知道要删除的行。要确认密钥是否正确在控制器发布操作中使用调试器,请检查传递给方法的categori
的密钥值。它有预期的价值吗?如果没有,您可能在视图中遇到问题,或者将表单和路由值绑定到categori
模型。如果是,请检查数据库中是否具有该键的实体位于数据库表中。如果是,则下一点。
该实体是否已经修改?如果您在Categori
模型中将另一个属性标记为并发令牌,则可能会发生EF“认为”它已在数据库中进行了修改(即使它没有)。如果在GET请求中加载实体并在POST请求中重新附加(将状态设置为Modified
)和SaveChanges
之间,数据库或视图中的属性已更改你会得到并发违规。
优先考虑上面的粗体测试,因为在我看来,这是问题的最可能原因。如果事实证明密钥没有更好的预期值,那么请问一个新问题,因为它将是一个纯粹的ASP.NET MVC问题,与EF和你的UOW和服务架构无关。