2008-09-02 9 views
4

たとえば、アプリケーションのデータアクセスレイヤを構築しています。通常、データベースに格納されているオブジェクトの種類ごとにクラス定義があります。もちろん、実際のデータアクセスでは、通常、結果の行ごとに1つのオブジェクトを作成するために必要なデータを使用して、データエリア、型指定されたデータ型または型指定されていないデータセットなどの形式でデータを取得します。データベース行からオブジェクトを作成する

データレイヤーでオブジェクトインスタンスを作成する方法を教えてください。データローを受け入れるコンストラクタはありますか?もしそうなら、そのタイプセーフな方法は?または、たとえ多くのフィールドがあっても、インスタンス化したい各フィールドの1つのパラメータをコンストラクタでリストしますか?このコンストラクタに 'internal'をマークしますか?

答えて

3

私は非常にORMツールを使用することをお勧めします。単純なプロジェクトでもORMを素早く静かに利用することができます...特にCastleActiveRecordツール(モデル宣言を簡略化するためにNHibernateの上に位置します)を見てください。

7

DataRowまたはSqlDataReaderに満足できない場合は、自分でホイールを再発明する代わりに、Linq to SqlまたはnHibernateなどのORMシステムを参照する必要があります。

(ちなみに、これは「ActiveRecordの」パターンと呼ばれる)

0

これらは、データのソースとしてより複雑なクエリをサポートしますか?たとえば、特定の状況で返されるレコードを決定するだけであっても、他のいくつかのテーブルに参加することができます。そして、彼らは自分が使っているクラスに独自のメソッドを追加させますか?

2

私は反射を使用してこれを達成しました。ここでは、オブジェクトのSelectステートメントから列の名前を付けます。

これは、テンプレートヘルパークラスがあることを前提としています。あなた自身をオブジェクトに配置したい場合は、すべてのTをオブジェクトに置き換えることができます。

これは一例です:

private T ObjectFromRow(DataRow row) 
{ 
    Type t = typeof(T); 

    T newObj = (T)Activator.CreateInstance(t); 


    System.Reflection.PropertyInfo[] properties = t.GetProperties(); 

    for (int i = 0; i < properties.Length; i++) 
    { 
     if (!properties[i].CanWrite) 
     { 
      continue; 
     } 

     if (!row.Table.Columns.Contains(properties[i].Name)) 
     { 
      continue; 
     } 

     if (row[properties[i].Name] == DBNull.Value) 
     { 
      continue; 
     } 

     if (properties[i].PropertyType == typeof(string)) 
     { 
      properties[i].SetValue(newObj, row[properties[i].Name], null); 
     } 
     else if (properties[i].PropertyType == typeof(double)) 
     { 
      properties[i].SetValue(newObj, double.Parse(row[properties[i].Name].ToString()), null); 
     } 
     else if (properties[i].PropertyType == typeof(int)) 
     { 
      properties[i].SetValue(newObj, int.Parse(row[properties[i].Name].ToString()), null); 
     } 
     else if (properties[i].PropertyType == typeof(DateTime)) 
     { 
      properties[i].SetValue(newObj, DateTime.Parse(row[properties[i].Name].ToString()), null); 
     } 
     else if (properties[i].PropertyType == typeof(bool)) 
     { 
      properties[i].SetValue(newObj, bool.Parse(row[properties[i].Name].ToString()), null); 
     } 
    } 

    return newObj; 
} 
1

@Joel(再:複雑なクエリ、参加する、など)

ザ・NHibernateの城ActiveRecordのツールは非常に複雑なクエリを処理し、クラス関係とAを経由して加入することができます徹底的な 'Expression'クラス(これはクエリメソッドに追加できます)または 'Hibernate Query Language'(HQL)の使用です。

これらの詳細については、documentationの公式をチェックするか、素晴らしいSummer of NHibernateスクリーンキャストをご覧ください。

1

NHibernate &の代わりに、SubSonicをご覧ください。これはActiveRecordも使用しますが、NHibernateよりもスイスアーミーナイフです。

EDIT:

Simple Select with string columns 

      int records = new Select("productID"). 
       From("Products").GetRecordCount(); 

      Assert.IsTrue(records == 77); 

Simple Select with typed columns 

      int records = new Select(Product.ProductIDColumn, Product.ProductNameColumn). 
       From<Product>().GetRecordCount(); 
      Assert.IsTrue(records == 77); 

そして、いくつかの更なるexamples

Standard Deviation 

    const double expected = 42.7698669325723; 

    // overload #1 
    double result = new 
     Select(Aggregate.StandardDeviation("UnitPrice")) 
     .From(Product.Schema) 
     .ExecuteScalar<double>(); 
    Assert.AreEqual(expected, result); 

    // overload #2 
    result = new 
     Select(Aggregate.StandardDeviation(Product.UnitPriceColumn)) 
     .From(Product.Schema) 
     .ExecuteScalar<double>(); 
    Assert.AreEqual(expected, result); 

    // overload #3 
    result = new 
     Select(Aggregate.StandardDeviation("UnitPrice", "CheapestProduct")) 
     .From(Product.Schema) 
     .ExecuteScalar<double>(); 
    Assert.AreEqual(expected, result); 

    // overload #4 
    result = new 
     Select(Aggregate.StandardDeviation(Product.UnitPriceColumn, "CheapestProduct")) 
     .From(Product.Schema) 
     .ExecuteScalar<double>(); 
    Assert.AreEqual(expected, result); 

そして、いくつかのWildcard methods

[Test] 
     public void Select_Using_StartsWith_C_ShouldReturn_9_Records() { 


      int records = new Select().From<Product>() 
       .Where(Northwind.Product.ProductNameColumn).StartsWith("c") 
       .GetRecordCount(); 
      Assert.AreEqual(9, records); 
     } 
ここ

は亜音速のドキュメントからsampleです

関連する問題