kmp*_*kmp 5 .net c# entity-framework-4.3
我正在使用来自ASP .NET MVC 3.0 Web应用程序的Entity Framework 4.3.1,我有一些代码可以分离旧对象并用一个看起来像这样的新对象替换它:
public void UpdateUnattached(T entryToUpdate, T updatedEntry)
{
var ctx = (EntityFrameworkContext) _context;
ctx.ChangeObjectState(EntityState.Detached, entryToUpdate);
_set.Attach(updatedEntry);
ctx.ChangeObjectState(EntityState.Modified, updatedEntry);
}
Run Code Online (Sandbox Code Playgroud)
这种情况一直有效,除了一种情况,当我_set.Attach在线下面得到例外情况时.
此RelationshipManager无法返回RelatedEnd.对于由ObjectStateManager跟踪或实现IEntityWithRelationships的对象,RelationshipEnd只能由RelationshipManager返回.
对象图非常深,我认为它告诉我有一个属性已被设置为某个对象没有在某处被跟踪(如果我错了请纠正我).所以,我的问题是......
我如何找出此异常的根本原因是什么?
我已经尝试在它周围放置一个try/catch并调用GetValidationErrorscatch但是同样会抛出同样的异常.
来自异常的更多信息(InnerException为空)......
Type: System.InvalidOperationException
Source: System.Data.Entity
Target site: GetRelatedEndInternal
Stacktrace: at System.Data.Objects.DataClasses.RelationshipManager.GetRelatedEndInternal(String relationshipName, String targetRoleName)
at System.Data.Objects.EntityEntry.FindRelatedEntityKeysByForeignKeys(Dictionary`2& relatedEntities, Boolean useOriginalValues)
at System.Data.Objects.EntityEntry.TakeSnapshotOfForeignKeys()
at System.Data.Objects.ObjectStateManager.PromoteKeyEntryInitialization(EntityEntry keyEntry, IEntityWrapper wrappedEntity, IExtendedDataRecord shadowValues, Boolean replacingEntry)
at System.Data.Objects.ObjectContext.AttachSingleObject(IEntityWrapper wrappedEntity, EntitySet entitySet, String argumentName)
at System.Data.Objects.ObjectContext.AttachTo(String entitySetName, Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Attach(Object entity)
at System.Data.Entity.DbSet`1.Attach(TEntity entity)
at ... snip ...
Run Code Online (Sandbox Code Playgroud)
这更多的是一种解决方法,而不是实际的解决方案......
我已经能够确定问题与集合属性有关。我怀疑 Linq 可能正在尝试填充空集合。
检查有问题的对象,我发现我可以像这样解决问题:
旧代码:
var myObject = db.MyObjectCollection.Find(x=>x.id = myId);
Run Code Online (Sandbox Code Playgroud)
新代码
var myCollection = db.MyObjectCollection.Where(x=>x.id = myId);
if(myCollection != null && myCollection.Count() > 0){
var myObject = myCollection.First();
}
Run Code Online (Sandbox Code Playgroud)
这解决了该错误。然而,这个解决方案的问题在于,它只能解决抛出错误的单一情况下的问题,并且不能保证它不会在其他地方出现。事实上,这有点像玩 Whack-Em-All,因为错误在其他情况下会再次出现。