6

Entity Framework を使用して親子の結果セットでデータをクエリしており、このデータを XML ドキュメントにエクスポートしたいと考えています。

var agreement = storeops.Agreements.SingleOrDefault(a => a.AgreementNumber == AgreementTextBox.Text);
XmlSerializer serializer = new XmlSerializer(agreement.GetType());
XmlWriter writer = XmlWriter.Create("Agreement.xml");
serializer.Serialize(writer, agreement);

これは、関連する子レコードを XML に含めずに親のみをシリアル化することを除けば、うまく機能します。子供たちもシリアル化するにはどうすればよいですか?

また、POCOで生成されたコードを使用してみましたが、シリアル化できないICollectionであることを除いて、子コレクションをシリアル化しようとしました。

型 System.Collections.Generic.ICollection`1[[DataSnapshots.AgreementItem, DataSnapshots, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] のメンバー DataSnapshots.Agreement.AgreementItems をシリアル化できません。これはインターフェイスであるためです。

4

2 に答える 2

10

XML シリアル化は、Entity Framework エンティティを操作する場合、バイナリ シリアル化およびデータ コントラクト シリアル化とは異なる動作をします。後者は、オブジェクト グラフに読み込まれた関連オブジェクトをシリアル化しますが、XML シリアル化はシリアル化しません。そのため、以下を使用する必要がありますDataContractSerializer

var agreement = storeops.Agreements.SingleOrDefault(a => a.AgreementNumber == AgreementTextBox.Text);
// make sure any relations are loaded

using (XmlWriter writer = XmlWriter.Create("Agreement.xml"))
{
    DataContractSerializer serializer = new DataContractSerializer(agreement.GetType());
    serializer.WriteObject(writer, agreement);
}

また、Entity Framework は、既定で 1:Many リレーションに対して遅延読み込みを使用します。シリアル化するときに、参照されるオブジェクトがまだ読み込まれていない場合は、それらを参照するキーだけが取得されます。関連するエンティティを呼び出すか、クエリでagreement.Children.Load()使用して明示的に読み込む必要があります (は関連するエンティティのコレクションの名前です)。.Include("Children")"Children"

于 2011-06-04T03:17:51.850 に答える
0

私は最終的にこれに対する解決策を見つけましたが、生成されたクラスを編集する必要があります:(

POCO で生成されたエンティティ クラスを作成し、Lazy Loading を true に設定します。これにより、1 回の選択で親とすべての子が取得されます (Include または Load を使用する必要はありません)。

親クラスで、子アクセサーの型を ICollection から FixupCollection に変更します。

public virtual FixupCollection AgreementItemLogs

次に、XmlSerializer で、プロキシ クラスから親の型と子の型を指定する必要があります。

var agreement = storeops.Agreements.Include("AgreementItems").SingleOrDefault(a => a.AgreementNumber == AgreementTextBox.Text);                                             
                var typeList = new List<Type>();

                if(agreement.AgreementItems.Count > 0)
                    typeList.Add(agreement.AgreementItems.FirstOrDefault().GetType());
                if (agreement.AgreementItemLogs.Count > 0)
                    typeList.Add(agreement.AgreementItemLogs.FirstOrDefault().GetType());
                if (agreement.AgreementPricings.Count > 0)
                    typeList.Add(agreement.AgreementPricings.FirstOrDefault().GetType());
                if (agreement.AgreementSnapshots.Count > 0)
                    typeList.Add(agreement.AgreementSnapshots.FirstOrDefault().GetType());
                if (agreement.AgreementTransactions.Count > 0)
                    typeList.Add(agreement.AgreementTransactions.FirstOrDefault().GetType());
                if (agreement.AgreementTransactionLogs.Count > 0)
                    typeList.Add(agreement.AgreementTransactionLogs.FirstOrDefault().GetType());

                XmlSerializer serializer = new XmlSerializer(agreement.GetType(), typeList.ToArray());
                XmlWriter writer = XmlWriter.Create("Agreement.xml");
                serializer.Serialize(writer, agreement);
于 2011-06-05T16:28:34.450 に答える