2016-11-05 2 views
1

私は、次の(擬似)コードを持っている...実際のコードは、はるかに複雑であるが、これは根本的な問題の要点である:Entity Framework 4.xで孤立したオブジェクトを防止するにはどうすればよいですか?

string customXML = GoFetchCustomXML(); 
    using (MyContext ctx = new MyContext(...)) 
    { 
     SomeTable tbl = CreateEntryInTable(customXML); 

     ctx.SomeTables.AddObject(tbl); 

     ctx.SaveChanges(); 
    } 


... 

public SomeTable CreateEntryInTable(string customXML) 
{ 
    XDocument doc = XDocument.Parse(customXML); 
    SomeTable ret = new SomeTable(); 

    foreach (XElement descendant in doc.Descendants("ChildObject").ToList()) 
    { 
     ChildTable ct = new ChildTable(); 

     // Set some initial items about ct based on 
     // customer configurations. It sets our StatusCodeID to "NEW". 
     initializeCT(ct, SomeGlobalCustomerObject); 

     if (ValidateChildObject(descendant, ct)) 
     { 
      // Set final ct properties here. We move the 
      // StatusCodeID to "Valid" among many other things. 

      // Before we go on, set CreateDate 
      ct.CreateDate = DateTime.Now; 

      ret.ChildTables.AddObject(ct); 
     } else { 
      // Do nothing. We've changed our mind about needing 
      // a ChildTable object. 
     } 
    } 

    return ret; 
} 

私はAを追いかけ今日8時間以上を費やしてきました非常に奇妙な問題です。 The element at index 0 in the collection of objects to refresh is in the added state. Objects in this state cannot be refreshed.

「子孫」の3番目のループでコードを実行すると、検証をパスしないため、ChildTablesには追加されません。これは有効でしょうか? (そうでない場合、私に教えてください)

- 私が辛抱強く発見したように - それは何とか文脈に追加されています。それはID列は実際には "0"です。プログラムが "SaveChanges()"になると、レコードの日付(作成日)が00/00/0001でデータベースで有効でないため、クラッシュします。私が接続にプロファイラを置くと、そのStatusCodeID == NEW ...が表示されますが、このレコードは決して完了せず、CTXオブジェクトまたはChildTablesには追加されませんでした。

さらに悪いことに、これがこの状態にあり、コンテキストはトーストです。私はそれを殺すためにこのレコードを見つけることができません、そして、それは文脈のどこかに孤立したレコードであるので何も保存することができません。

「無効な」オブジェクトをスキップするか、オブジェクトが作成されないように私のコードを書き直して、実際に必要となり、ChildTablesに追加されるまでは書き直してください。しかし、私が上で行ったことは合法的でなければならないでしょうか?そうでない場合、なぜ誰かが説明することができますか?

+0

'ct'は' initializeCT() 'の文脈に付けられていると思います。 –

+0

いいえ。コード内のコンテキストには結び付けられません。私はそれを確認した。 – Jerry

答えて

0

答えが見つかったか、少なくとも非常に重大な回避策が見つかりました。

1)オブジェクトを追加する必要があると確信できない限り、オブジェクトを作成しないでください。 ValidateChildObjectを再作成して、DescendantとSomeCustomerObjectを使用して、有効かどうかを判断し、ルールが合格した場合にのみcreateおよびinitializeCTを行うことができます。

2)しかし、現在のデザインでは実現できない場合があります。設定を検証するために何をしなくても、設定をやり直す必要がありますinitializeCTの値。これらの場合には、上記の「ELSE」句のように、私は実行する必要があります。私は、これら2つのアプローチのいずれかを実行すると

... 
} 
else 
{ 
    // Remove it from the ChildTables anyway, just in case 
    // it was magically added. If it was not added, this does not fail. 
    ctx.ChildTables.DeleteObject(ct); 
} 

、私のコードは、スムーズに実行されます。

関連する問題