5

我正在使用 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);
}

这一直有效,除了一种情况,当我得到下面的异常时_set.Attach

此RelationshipManager 不能返回RelatedEnd。对于由 ObjectStateManager 跟踪或实现 IEntityWithRelationships 的对象,RelatedEnd 只能由 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 ...
4

2 回答 2

0

通过查看错误消息,我猜测您正在尝试附加与 ObjectStateManager 未跟踪的其他对象(即可能不是实体)有关系的东西。

于 2013-07-05T07:03:24.923 回答
0

这更像是一种解决方法,而不是实际的解决方案......

我已经能够确定问题与作为集合的属性有关。我怀疑 Linq 可能正在尝试填充空集合。

检查有问题的对象,我发现我可以解决这样的问题:

旧代码:

var myObject = db.MyObjectCollection.Find(x=>x.id = myId);

新代码

 var myCollection = db.MyObjectCollection.Where(x=>x.id = myId);
 if(myCollection != null && myCollection.Count() > 0){
     var myObject = myCollection.First();
 }

这解决了错误。但是,此解决方案的问题在于它仅在引发错误的单一情况下解决了问题,并且不能保证它不会在其他地方出现。事实上,这有点像玩 Whack-Em-All,因为错误在其他情况下会再次出现。

于 2013-07-01T05:17:15.453 回答