我有以下关于实体更新的问题。下面给出的是我的 WCF 方法。(更新由公共Save方法判断是更新还是添加后调用)
protected bool UpdateSalesMaster(SalesMaster order)
{
using (var context = new MyContext())
{
SalesMaster original = context.SalesMasters.FirstOrDefault(o => o.OrderID == order.OrderID);
if (original != null)
{
context.Entry(original).CurrentValues.SetValues(order);
foreach (SalesDetail detail in order.SalesDetails)
{
if (detail.OrderDetailID == 0)
context.SalesDetails.Add(detail);
else
{
SalesDetails originalDetail = context.SalesDetails.FirstOrDefault(o => o.OrderDetailID == detail.OrderDetailID);
if (originalDetail != null)
context.Entry(originalDetail).CurrentValues.SetValues(detail);
}
}
context.SaveChanges();
return true;
}
else
{
throw new FaultException(string.Format("Invalid Order specified: {0}", order.OrderID));
}
}
}
当我只更新 SalesMaster 中的 OrderDate 并且不更改任何细节时,会向数据库触发更新查询以获取详细信息。我希望只看到 SalesMaster 的更新查询。
有人可以让我知道我在这里做错了什么吗?如果没有任何更改,我不想向数据库发起更新查询。
我使用从数据库中获取原始值的方法来确定是否使用 context.Entry(originalDetail).CurrentValues.SetValues(detail); 更新了任何值。
我还通过检查实体的 IAuditable 实现来覆盖 SaveChanges 以设置 LastModified 日期。这是我发现详细实体的状态被标识为已修改的时候。但是数据库中发生的唯一更新是 LastModifiedBy,它在我的保存更改中进行了更新。我不确定当没有详细更改时它是如何设置为已修改状态的。
public override int SaveChanges()
{
var changeSet = ChangeTracker.Entries<IAuditable>();
if (changeSet != null)
{
foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
{
if (entry.State == EntityState.Added)
entry.Entity.DateCreated = DateTime.Now;
if (entry.State == EntityState.Modified)
{
entry.Property(a => a.CreatedByUser).IsModified = false;
entry.Property(a => a.DateCreated).IsModified = false;
}
entry.Entity.DateModified = DateTime.Now;
}
}
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
throw ex;
}
}
我的解决方案结构是:
- 客户端 - Windows 窗体 UI
- 实体 - POCO 作为单独的库
- WCF - 所有业务逻辑,添加、更新、删除对象。
- 数据 - 具有流畅映射的实体框架上下文。