2

xsd から生成されるクラスのインスタンスを作成する一般的なソリューションを作成する必要があります。例えば:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PS">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="P" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="FXs" maxOccurs="1" minOccurs="0">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="FX" minOccurs="1">
                      <xs:complexType>
                        <xs:attribute name="asOfDate" type="xs:date" use="required" />
                        <xs:attribute name="currency" type="xs:string" use="required" />
                        <xs:attribute name="rate" type="xs:decimal" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
 </xs:sequence>
            <xs:attribute name="PName" type="xs:string" />
            <xs:attribute name="currency" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

この xsd ランタイムからアセンブリを生成すると、クラス PS、PSP、および PSFX が含まれます。この場合、私はプロパティと何を期待するかを知っているので、createinstance と getproperties と setvalue が機能します。ポートフォリオには PortfoliosPortfolio の配列があることを知っています。

case "PS":
                                    if (p== null)
                                        p= myAssembly.CreateInstance(cls.FullName);
                                    break;

                                case "PSP":
                                    myClass = myAssembly.CreateInstance(cls.FullName);
                                    myClass.GetType().GetProperty("PName").SetValue(myClass, dt.Rows[0]["PortfolioName"].ToString(), null);
                                    myClass.GetType().GetProperty("currency").SetValue(myClass, dt.Rows[0]["Currency"].ToString(), null);
                                    if (myClasses == null)
                                        myClasses = Array.CreateInstance(myClass.GetType(), deals.Count());
                                    myClasses.SetValue(myClass, l);
                                    l++;
                                    portfolio.GetType().GetProperty("P").SetValue(p, myClasses, null);

ここで、任意の xsd (上記だけでなく) を取り、アセンブリを生成できる汎用ソリューションが必要です。私はすでにアセンブルを生成しましたが、そこに存在するプロパティがわからないクラスにプロパティを動的に割り当てるにはどうすればよいですか? つまり、一般的なソリューションを作成するときに、クラスが別のクラスのオブジェクトのリストを使用していることをどのように知ることができるかということです。したがって、クラス名とプロパティ名をハードコーディングする代わりに、インスタンスとプロパティを取得する方法があります。上記のスニペットからわかるように、データセットの値をプロパティに割り当てています。計画では、データベースに値を columnname、attributename、parentnode として格納します。したがって、P ノードの PName 属性は列名 Pname から取得されます。コードにハードコーディングがないように設計したいと考えています。

申し訳ありませんが、ご容赦ください。意味が分からない場合はお知らせください。

4

2 に答える 2

1

長い質問には長い答えが必要です:

I.まず、ちょっとした資格情報: 私はしばらくの間、クラス/アセンブリの生成に取り組んできました。実際、 CodeDom (推奨される方法) またはIL Emitを使用してこれを行うことができます。しかし、おそらくそうすべきではありません。

  • これに対する最初の反論は、あなたの XML モデルはあまり役に立たないということです。これで、クラスに変換したい XML ができました。そのためには、何らかの方法でその XML をコード (C#、VB、または IL のいずれか) に変換し、実行時にコンパイルして動的クラスを作成します。では、XML の代わりにコードを直接使用してみませんか?
  • 上記のポイントには当然の結果があります。設計時にクラスを指定している場合、クラスをコンパイルしないのはなぜですか (したがって、コンパイル時にクラスを生成します)。

Ⅱ.ここでの設計ドライバーは、ハード コードではありません

  • 最初の哲学的分析:コードをハードコーディングしたくないというパラドックスです。
  • ソース内のハードコーディングされた文字列を最小限に抑えることは良い習慣です。主な理由は、(1) これらの文字列は変更されることが予想される (2) テストが容易になる可能性があるためです。この定義から 2 つのことを抽出できます。
    • プログラム構造ではなく、ハードコード文字列を避ける必要があります
    • コンパイル時に変更 (「動的」) が予想されるもの、または未知のもののみを構成可能にする必要があります。データベース構造はほとんど当てはまりません。

抽象的に考えると、ハードコードを避けることができますか? あなたの例では、処理しようとしている XML ファイル内のデータを参照するいくつかの文字列を既に使用しています。処理したいデータに関する情報がないと、プログラムはどのように機能するのでしょうか?

(はい、答えがあります)

...

回答: データを表示するだけの場合、つまり、完全なデータ構造はプログラム ロジックには関係ありません。この例は、テキスト エディタです。テキスト エディターは、事前にデータについて知る必要はありません。ファイルに存在するようにレンダリングします。

ただし、あなたの場合、データベースはデータの「マスター」です。それをあなたのプログラムから分離しようとしても無駄です。

于 2012-06-01T23:49:41.357 に答える
0

XML を解析するだけで、アセンブリを作成しない方が簡単ではないでしょうか? データベースに必要なすべての情報を抽出するために、XmlSchema とその子オブジェクトを使用できます。XML 出力を操作するために、XML ドキュメントを処理するための一般的なフレームワークを使用できます。または、本当にアセンブリが必要な場合は、最初に XML を変更してから、それをオブジェクトに逆シリアル化することができます。

ただし、クライアント コードがコンパイル時にアセンブリの CLR 型を認識していない場合、そもそもアセンブリを作成しても意味がないと思います。一般的な中間データ形式を作成する方がよいでしょう。必要に応じて XML またはデータベース列に変換できます。

于 2012-06-01T18:25:19.973 に答える