ObjectStateEntry 状态的奇怪行为
我有以下扩展方法,但我不确定为什么在对一个条目调用 entry.AcceptChanges()
后每个条目状态都更改为“Unchanged”。
public static void SaveWithLogging(this ObjectContext context)
{
IEnumerable<ObjectStateEntry> entries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added | EntityState.Deleted);
foreach (var entry in entries)
CreateTransactionLog(context, entry);
}
private static void CreateTransactionLog(ObjectContext context, ObjectStateEntry entry)
{
using (TransactionScope transaction = new TransactionScope())
{
string operationType = entry.State.ToString();
context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
if (entry.State == EntityState.Added) entry.AcceptChanges();
var columnNames = (from p in entry.EntitySet.ElementType.Members
select p.Name)
.ToList();
Log log = new Log();
log.CreateDate= DateTime.Now;
log.UserName = "Test";
log.Operation = operationType;
context.AddObject("Logs", log);
foreach (var columnName in columnNames)
{
string oldValue = entry.State == EntityState.Added ? string.Empty : entry.OriginalValues[columnName].ToString();
string newValue = entry.CurrentValues[columnName].ToString();
if (oldValue.CompareTo(newValue) != 0)
{
// Create Log Details
LogDetail logDetails = LogDetail();
logDetails.LogId = log.LogId;
logDetails.TableName = entry.EntitySet.Name.ToString();
logDetails.Field = columnName.ToString();
logDetails.Before = oldValue;
logDetails.After = newValue;
logDetails.PKValue = entry.CurrentValues[0].ToString();
context.AddObject("LogDetails", logDetails);
}
}
context.SaveChanges();
transaction.Complete();
}
}
我做错了什么吗?
I have the following extension method and I'm not sure why each entries state is being changed to Unchanged after I call entry.AcceptChanges()
on one entry.
public static void SaveWithLogging(this ObjectContext context)
{
IEnumerable<ObjectStateEntry> entries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added | EntityState.Deleted);
foreach (var entry in entries)
CreateTransactionLog(context, entry);
}
private static void CreateTransactionLog(ObjectContext context, ObjectStateEntry entry)
{
using (TransactionScope transaction = new TransactionScope())
{
string operationType = entry.State.ToString();
context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
if (entry.State == EntityState.Added) entry.AcceptChanges();
var columnNames = (from p in entry.EntitySet.ElementType.Members
select p.Name)
.ToList();
Log log = new Log();
log.CreateDate= DateTime.Now;
log.UserName = "Test";
log.Operation = operationType;
context.AddObject("Logs", log);
foreach (var columnName in columnNames)
{
string oldValue = entry.State == EntityState.Added ? string.Empty : entry.OriginalValues[columnName].ToString();
string newValue = entry.CurrentValues[columnName].ToString();
if (oldValue.CompareTo(newValue) != 0)
{
// Create Log Details
LogDetail logDetails = LogDetail();
logDetails.LogId = log.LogId;
logDetails.TableName = entry.EntitySet.Name.ToString();
logDetails.Field = columnName.ToString();
logDetails.Before = oldValue;
logDetails.After = newValue;
logDetails.PKValue = entry.CurrentValues[0].ToString();
context.AddObject("LogDetails", logDetails);
}
}
context.SaveChanges();
transaction.Complete();
}
}
Am I doing something incorrectly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,这是正确的。 ObjectStateEntry.AcceptChanges< /em> 类似于 ObjectContext。 AcceptAllChanges,除非它将仅影响特定实体。
重要的一点是,默认情况下,SaveChanges 方法在执行数据库修改后会调用 AcceptAllChanges 方法。然后AcceptAllChanges将每个附加实体的当前值推送到原始值,然后将其EntityState更改为未更改。
正如您所看到的,您的问题来自于 context.SaveChanges() 在 foreach 的第一次迭代中被调用,因此 AcceptAllChanges()< /em> 由 SaveChanges() 调用,使每个人都进入“Unchanged”状态。
Yes, that is correct. ObjectStateEntry.AcceptChanges is similar to ObjectContext.AcceptAllChanges, except that it will impact only the specific entity.
The important point is that by default, the SaveChanges method calls AcceptAllChanges method after it has performed the database modifications. Then AcceptAllChanges pushes the current values of every attached entity into the original values and then changes their EntityState to Unchanged.
As you can see, your issue coming from the fact that context.SaveChanges() is called on the first iteration of your foreach, therefore a AcceptAllChanges() is invoked by SaveChanges() and that make everyone to go into Unchanged state.
AcceptChanges 方法按设计执行此操作.
您期望什么行为?
The AcceptChanges method does this by design.
What behavior do you expect?