gpt4 book ai didi

wpf - 为什么在我的WPF应用程序中有时会发生此 Entity Framework 崩溃?

转载 作者:行者123 更新时间:2023-12-03 17:14:20 25 4
gpt4 key购买 nike

我管理一个使用Entity Framework 6.1(模型优先ObjectContext)和SQLite数据库的WPF应用程序。

我的应用程序的第一个崩溃日志(根据HockeyApp)如下(带有指向我的应用程序代码的指针标记为****):

System.InvalidOperationException: The property 'Id' is part of the object's key information and cannot be modified. 
at System.Data.Entity.Core.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata, Int32 ordinal, String memberName)
at System.Data.Entity.Core.Objects.EntityEntry.GetAndValidateChangeMemberInfo(String entityMemberName, Object complexObject, String complexObjectMemberName, StateManagerTypeMetadata& typeMetadata, String& changingMemberName, Object& changingObject)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName, Object complexObject, String complexObjectMemberName)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.Core.Objects.ObjectStateEntry.System.Data.Entity.Core.Objects.DataClasses.IEntityChangeTracker.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.Core.Objects.DataClasses.EntityObject.ReportPropertyChanging(String property)
****
at MyNamespace.MyApp.MyEntity.set_Id(Int64 value) in C:\MyPath\MyApp\EfGeneratedEntities.cs
****
at lambda_method(Closure , Object , Object )
at System.Data.Entity.Core.Objects.DelegateFactory.SetValue(EdmProperty property, Object target, Object value)
at System.Data.Entity.Core.Objects.StateManagerMemberMetadata.SetValue(Object userObject, Object value)
at System.Data.Entity.Core.Objects.Internal.LightweightEntityWrapper`1.SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, Int32 ordinal, Object target, Object value)
at System.Data.Entity.Core.Objects.EntityEntry.SetCurrentEntityValue(StateManagerTypeMetadata metadata, Int32 ordinal, Object userObject, Object newValue)
at System.Data.Entity.Core.Objects.ObjectStateEntryDbUpdatableDataRecord.SetRecordValue(Int32 ordinal, Object value)
at System.Data.Entity.Core.Mapping.Update.Internal.PropagatorResult.SetServerGenValue(Object value)
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.BackPropagateServerGen(List`1 generatedValues)
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__d()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClassb.<SaveChangesInternal>b__8()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges()
****
at MyNamespace.MyApp.MyContext.OnMyEvent() in C:\MyPath\MyApp\MyContext.cs
****

我无法重现此崩溃,因此也无法尝试修复它。我很想整理一下。

我了解崩溃消息。但是我的应用程序没有执行任何可能导致此问题的操作。 MyEntity.Id属性是一个实体键( StoreGeneratedPattern = Identity),我从不手动设置 Id值。我从不手动将实体标记为已修改。我的SQLite数据库没有任何触发器或其他可能与EF对数据库生成的标识值的解释相混淆的触发器。我真的不知道这种崩溃是怎么发生的,我自己也无法实现—插入新实体对我来说也很好。

我当然不希望任何人阅读这篇文章并提出解决方案,但是我希望有人可以带领我朝着正确的方向前进。

哪些非显而易见的原因可能导致此崩溃发生?

我敢肯定我会被要求提供源代码,但实际上并没有太多。在罪魁祸首代码中,我只创建了一个 MyEntity对象,设置了一些属性值,将其添加到上下文中,然后调用 SaveChanges()。而已。就像我说的那样,它在我的测试中效果很好,可以满足99%的客户使用率。但是我每天都会收到这样的崩溃报告,所以我想结束它们。

----更新----

我认为值得指出的是,堆栈跟踪中的 MyEntity.set_Id(Int64 value)显然是Entity Framework的键/标识值检索的一部分(请参见 PropagatorResult.SetServerGenValue(Object value)周围的行等)。这不是我设置 Id的代码,它是EF。

查看 Entity Framework source code,当尝试为不在 Added状态的实体设置实体键值时,抛出此异常:
// Key fields are only editable if the entry is the `Added` state.
if (member.IsPartOfKey
&& State != EntityState.Added)
{
throw new InvalidOperationException(Strings.ObjectStateEntry_CannotModifyKeyProperty(memberName));
}

那么问题是否可能是MyEntity在 Modified之前(或在 SaveChanges()期间但在身份值检索之前)处于某种替代状态(例如 SaveChanges())?

这怎么可能? 如前所述,我并不是在任何地方手动设置状态。

最佳答案

解决了。

我的堆栈跟踪底部的MyNamespace.MyApp.MyContext.OnMyEvent()行在计划的时间执行。

事实证明,有可能同时安排两个或更多执行。在某些情况下(即使在我的测试中也不一致,并且无论如何通常都能正常工作),这将导致此崩溃,大概是因为当在近乎瞬时的距离完成多个数据库插入操作时,SQLite的EF生成的ID检索可能被触发。

无论如何,解决方案是简单地将代码包装在MyNamespace.MyApp.MyContext.OnMyEvent()语句中的lock { ... }中,以防止并发执行。

关于wpf - 为什么在我的WPF应用程序中有时会发生此 Entity Framework 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39541002/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com