Entity framework 5 EntityState.与EntityState.Modified相比未发生任何更改
使用EF5 winforms,我想确定数据在我的上下文中是否已更改。 我的问题是,如果调用了DetectChanges,则EntityState.Modified将为true,而不管任何值是否已更改 为此,我使用以下代码片段Entity framework 5 EntityState.与EntityState.Modified相比未发生任何更改,entity-framework-5,Entity Framework 5,使用EF5 winforms,我想确定数据在我的上下文中是否已更改。 我的问题是,如果调用了DetectChanges,则EntityState.Modified将为true,而不管任何值是否已更改 为此,我使用以下代码片段 foreach (var e in Db.ChangeTracker.Entries()) { switch (e.State) { case EntityState.Unch
foreach (var e in Db.ChangeTracker.Entries())
{
switch (e.State)
{
case EntityState.Unchanged :
break;
case EntityState.Deleted:
break;
case EntityState.Added:
break;
case EntityState.Modified:
var original = this.enumerateOriginalValues(e);
var current = this.enumerateCurrentValues(e);
if (original == current) sChanges = "No Changes";
else sChanges = string.Format("Was: {0} Is: {1}", original, current);
break;
}
// build string indicating No Changes or UnChanged
s = string.Format("{0} \r\n {1} {2} {3},{4}", s, sType, sKey, sState, sChanges);
}
有没有更好的方法来确定上下文是否发生了变化
[更新]
在格特的建议下,我在塞特的一处房产上设置了一个缺口。我在调用堆栈中找到了以下过程。
qry.载重线导致设定器起火
public override void Refresh()
{
try
{
try
{
if (base.bindingSource.DataSource != null)
{
var per = (Person)base.bindingSource.Current;
this.SaveChangesIfNeeded();
}
DbSet<Person> dset = base.Context.People;
if (this.QuickSearch == null)
{
this.QuickSearch ="";
}
IQueryable<Person> qry;
if (this._organisationId == 0)
{
qry =
dset.Where(
p => p.LastName.Contains(this.QuickSearch) || p.FirstName.Contains(this.QuickSearch));
}
else
{
qry =
dset.Where(
p =>
(p.LastName.Contains(this.QuickSearch) || p.FirstName.Contains(this.QuickSearch)) &&
(p.Organisation.Id == this._organisationId));
}
qry.Load(); // Setter is called here
base.bindingSource.DataSource = dset.Local.ToBindingList();
}
catch (Exception ex)
{
DialogResult dialogResult = MessageBox.Show(ex.Message);
throw;
}
}
catch (Exception ex)
{
HandleException.Show(ex);
}
}
这就是实体被物化的时候。通过导航而不是修改任何东西,看看断点是否在绑定后被命中是很有趣的。是的。我用call stack.OK更新了这个问题,所以导航确实设置了值。这太可悲了(我认为不必要)。但是,在(您的)
DbContext
API中,将属性设置为其原始值并不会将属性标记为已更改,因为DetectChanges()
实际上会比较值。在ObjectContext
API的生成代码中,设置任何值都将触发对象的PropertyChanged,并将状态设置为Modified(我不知道这一差异,因此我在下面进行了评论)。因此,为了增加一些混淆,在您的情况下,除非有真正的更改,否则此绑定问题不应该“修改”对象。看起来“some”属性总是被更改的,无论是通过绑定还是代码的其他部分。
> SBD.Syrius.DomainClasses.dll!SBD.Syrius.DomainClasses.Person.Title.set(string value) Line 537 C#
[Native to Managed Transition]
System.dll!System.ComponentModel.ReflectPropertyDescriptor.SetValue(object component, object value) + 0x197 bytes
System.Windows.Forms.dll!System.Windows.Forms.BindToObject.SetValue(object value) + 0x8a bytes
System.Windows.Forms.dll!System.Windows.Forms.Binding.PullData(bool reformat, bool force) + 0x26e bytes
System.Windows.Forms.dll!System.Windows.Forms.BindingManagerBase.PullData(out bool success) + 0x118 bytes
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.CurrencyManager_PullData() + 0x2f bytes
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.EndCurrentEdit() + 0x27 bytes
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.ChangeRecordState(int newPosition, bool validating, bool endCurrentEdit, bool firePositionChange, bool pullData) + 0xf3 bytes
System.Windows.Forms.dll!System.Windows.Forms.CurrencyManager.Position.set(int value) + 0x5b bytes
System.Windows.Forms.dll!System.Windows.Forms.BindingNavigator.OnMoveNext(object sender, System.EventArgs e) + 0x2b bytes
System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleClick(System.EventArgs e) + 0xb6 bytes
System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleMouseUp(System.Windows.Forms.MouseEventArgs e) + 0x237 bytes
System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.OnMouseUp(System.Windows.Forms.MouseEventArgs mea) + 0xef bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0x48b bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0xe14 bytes
System.Windows.Forms.dll!System.Windows.Forms.ToolStrip.WndProc(ref System.Windows.Forms.Message m) + 0x8c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x14c bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x681 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x57c bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x6f bytes
SBD.Syrius.UI.exe!SBD.Syrius.UI.Program.Main(string[] args) Line 57 + 0x9 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x66 bytes
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x8d bytes
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes
[Native to Managed Transition]