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 を返すことができません。RelatedEnd は、ObjectStateManager によって追跡されるオブジェクト、または IEntityWithRelationships を実装するオブジェクトの RelationshipManager によってのみ返すことができます。 

オブジェクト グラフは非常に深く、どこかで変更が追跡されていないオブジェクトに設定されているプロパティがあることを示していると思います (間違っている場合は修正してください)。それで、私の質問は...

この例外の根本原因を特定するにはどうすればよいですか?

その周りにtry/catchを配置GetValidationErrorsしてcatchを呼び出してみましたが、それも同じ例外でスローされます。

例外からの詳細情報 ( InnerExceptionis null)...

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

これは、実際の解決策というよりも回避策です...

問題がコレクションである属性に関連していると判断できました。Linq が null コレクションに値を設定しようとしている可能性があると思われます。

問題のあるオブジェクトを調べたところ、次のように問題を回避できることがわかりました。

古いコード:

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 に答える