关于Entity Framework DbContext SaveChanges 返回0的求助

beckfun 2014-10-30 08:06:44
直切话题, 采用的是Entity Framework+UnitOfWork+Repository+Autofac
UnitOfWork和Repository都是基础代码。网上直接都能搜到,不过按照管理,问问题,还是要贴源码
UnitOfWork的代码

public class UnitOfWork : DbContext, IUnitOfWork
{
/// <summary>
/// 构造方法。
/// </summary>
protected UnitOfWork()
{
}
/// <summary>
/// 构造方法。
/// </summary>
protected UnitOfWork(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}

/// <inheritdoc />
public void Flush()
{
try
{
var i = base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
this.Clear();
List<string> errorMessageList=new List<string>();
foreach (var entityValidationError in ex.EntityValidationErrors)
{
errorMessageList.Add(entityValidationError.Entry.Entity.ToString());
foreach (var validationError in entityValidationError.ValidationErrors)
{
errorMessageList.Add(string.Format("属性({0})引发了一个验证错误:{1}", validationError.PropertyName, validationError.ErrorMessage));
}
}
throw new Exception(string.Join(";\\n", errorMessageList.ToArray()));
}
catch (DbUpdateConcurrencyException ex)
{
throw new OptimisticConcurrencyException();
}
}

/// <inheritdoc />
public void Clear()
{
base.ChangeTracker.Entries()
.ToList()
.ForEach(entry => entry.State = EntityState.Detached);
}
}

Repository的源码

public class Repository<TUnitOfWork, TAggregateRoot, TId> : IRepository<TAggregateRoot, TId>
where TUnitOfWork : UnitOfWork
where TAggregateRoot : class, IAggregateRoot<TId>
{
private readonly UnitOfWork _unitOfWork;
/// <summary>
/// 构造方法。
/// </summary>
protected Repository(TUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}

/// <inheritdoc />
public bool Contains(TAggregateRoot item)
{
return _unitOfWork.Entry(item).State != EntityState.Detached;
}

/// <inheritdoc />
public void Save(TAggregateRoot item)
{
this.BeforeSave(item);
_unitOfWork.Set<TAggregateRoot>().Add(item);
}

/// <summary>
/// 模板方法子方法。
/// </summary>
protected virtual void BeforeSave(TAggregateRoot item) { }

/// <inheritdoc />
public void Update(TAggregateRoot item)
{
_unitOfWork.Entry(item).State = EntityState.Modified;
}

public void Delete(TAggregateRoot item)
{
_unitOfWork.Entry(item).State = EntityState.Deleted;
}

public void Merge(TAggregateRoot item)
{
var persistItem = _unitOfWork.Set<TAggregateRoot>().Find(item.Id);

_unitOfWork.Entry(persistItem).CurrentValues.SetValues(item);
}

public void Detach(TAggregateRoot item)
{
_unitOfWork.Entry(item).State = EntityState.Detached;
}

public void Attach(TAggregateRoot item)
{
_unitOfWork.Entry(item).State = EntityState.Unchanged;
}

public TAggregateRoot Load(TId id)
{
return _unitOfWork.Set<TAggregateRoot>().Find(id);
}


public void Refresh(TAggregateRoot item)
{
_unitOfWork.Entry(item).Reload();
}

public DbSet<TAggregateRoot> Set<TAggregateRoot>() where TAggregateRoot : class
{
return _unitOfWork.Set<TAggregateRoot>();
}
public IUnitOfWork UnitOfWork
{
get
{
return _unitOfWork;
}
}

/// <summary>
/// 数据库上下文。
/// </summary>
protected DbContext DbContext
{
get
{
return _unitOfWork;
}
}
}


Service调用


public class Service<TUnitOfWork,TRepository >
{
public TRepository Repository
{
get
{
if (null == _repository)
{
_repository = UnitOfWork.CreateRepository<TRepository>();
}

return _repository;
}
}
protected TUnitOfWork UnitOfWork
{
get
{
return Service<TUnitOfWork>();
}
}
public void Create(TAggregateRoot aggregate)
{
this.Repository.Save(aggregate);

this.UnitOfWork.Flush();
}
}

调用
new Service().Create(实体);断点监视,发现 SaveChanges 返回0,数据库没有任何动静,最奇怪的是用new Service().Repository.Set<T>() 查询的时候EF会生成SQL语句,更奇怪的是,之前也有用在一个项目上实践过可以正常使用,我也反复对比了两个项目,可以说代码基本一致。这是什么情况?在什么情况下SaveChanges 的返回值会是0,求助,问题解决,马上结贴!
...全文
663 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
beckfun 2014-10-30
  • 打赏
  • 举报
回复
引用 5 楼 feiyun0112 的回复:
看看Repository和UnitOfWork用的是不是同一个_unitOfWork
自己发现问题了。坑爹,其实上次这项目在别的项目也遇到了。是我向Autofac注册的问题。

registry.RegisterType(IUnitOfWorkType,UnitOfWorkType, LifeStyle.Singleton);
//改成
registry.RegisterType(UnitOfWorkType, LifeStyle.Singleton);
就可以了。
beckfun 2014-10-30
  • 打赏
  • 举报
回复
引用 5 楼 feiyun0112 的回复:
看看Repository和UnitOfWork用的是不是同一个_unitOfWork
是同一个。
feiyun0112 2014-10-30
  • 打赏
  • 举报
回复
看看Repository和UnitOfWork用的是不是同一个_unitOfWork
beckfun 2014-10-30
  • 打赏
  • 举报
回复
引用 3 楼 feiyun0112 的回复:
_unitOfWork.Set<TAggregateRoot>().Add(item); 改成 _unitOfWork.Entry(item).State = EntityState.Added;
谢谢斑竹的回复,不管用,SaveChange返回还是0。
feiyun0112 2014-10-30
  • 打赏
  • 举报
回复
_unitOfWork.Set<TAggregateRoot>().Add(item);
改成
_unitOfWork.Entry(item).State = EntityState.Added;
beckfun 2014-10-30
  • 打赏
  • 举报
回复
忘记补充了。是用的Code First

62,266

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧