3

アプリケーション オブジェクトのプロパティの大部分を含む基本クラスから継承するオブジェクト タイプを持つアプリケーションがあります。すべてのオブジェクト タイプは、データベース内の 1 つのテーブルに格納されます。「ClassType」列は、SqlDataReader 行をキャストするオブジェクトの種類を決定します。

これが私の現在の実装です:

SqlDataReader dr = SqlServerHelper.ExecuteReader("MyStoreProc", MySqlParmas);

if(dr.HasRows)
{
    while(dr.Read())
    {
        switch(dr["ClassType"].ToString())
        {
            case "ClassA":
                //cast sqldatareader a ClassA object
                ClassA a = new ClassFactory.CreateClassA(object p1, object p2);
            case "ClassB":
                //cast sqldatareader a ClassB object
                ClassB b = new ClassFactory.CreateClassB(object p1, object p2);
        //it continues for all objects with app....
        }
    }
}

dr.Close()

私の質問は、このタイプの処理のより良い実装ですか?

4

5 に答える 5

6

このアプローチは、コード生成 ORM に切り替えたくない場合です。

オブジェクトのテーブルに、オブジェクトの完全修飾型名を含めます。

次に、次のようなことができます。

    private Dictionary<String, Type> _objectTypes = new Dictionary<String, Type>();

    public ObjectFactory()
    {
        // Preload the Object Types into a dictionary so we can look them up later
        foreach (Type type in typeof(ObjectFactory).Assembly.GetTypes())
        {
            if (type.IsSubclassOf(typeof(BaseEntity)))
            {
                _objectTypes[type.Name.ToLower()] = type;
            }
        }
    }

すべてプリロードされたマッパーを使用して、コードを次のように置き換えることができます。

    string objectName = dr["ClassType"].ToString().ToLower();
    Type objectType;

    if (_objectTypes.TryGetValue(objectName, out objectType))
    {
       return (BaseEntity)Activator.CreateInstance(objectType,reader);
    }        

リーダーをオブジェクトのコンストラクターに渡して、それ自体が完全に読み込まれるようにします。そのタイプのコードはファクトリに属しません。

于 2008-11-18T23:57:54.723 に答える
5

これについては、オブジェクト リレーショナル マッパーに傾倒すると思います。NHibernateは、.NET プラットフォーム向けの既存の無料の成熟した ORM ソリューションの一例です。

于 2008-11-18T23:49:48.563 に答える
0

フィードバックをありがとうございます。しかし、サードパーティ製のツールや新しい言語を実装したくありません。今すぐ学習する時間がないからです。

@ジョナサンホラード:

私のオブジェクト モジュールは現在、次のように設計されています。

public class BaseClass
{
    public BaseClass() { }

    public object p1 { get; set;}

    public object p2 { get; set; }

    public virtual void ImplementLogic()  
    {
        //do some fun stuff....
    }
}

public class ClassA : BaseClass
{
    public ClassA { }

    public override void ImplementLogic()
    {
        //make it rain.....
    }
} 

public class ClassB : BaseClass
{
    public ClassB { }    

    public override void ImplementLogic()
    {
        //do some more fun stuff
    }
}

このモデルではど​​のように機能しますか?

BaseClassFactory コンストラクターは BaseClass から継承したすべてのクラスを認識するので、最初のコード サンプルを BaseClassFactory コンストラクターにスローしますか?

于 2008-11-19T00:12:46.770 に答える
0

完全修飾型名をデータベースに保存し、Activator.GetInstance. これにより、醜い switch ステートメントが取り除かれますが、ファクトリ メソッドの代わりに型のコンストラクターが呼び出されます。それはあなたが望むことをしますか?

于 2008-11-19T00:45:41.163 に答える
0

LINQ to SQL は正当な選択肢かもしれません。ただし、主キーと外部キーで適切に制約されていないデータベースではうまく機能しません。テーブルに基づいてクラスを生成します。

于 2008-11-18T23:55:34.027 に答える