2012-03-23 14 views
1

私はロード時にSQLデータベースからデータを取り込むような20のフィールドを持つクラスを持っています。現在、私はSQLのprocを呼び出し、すべての必要なフィールドに値を設定するコンストラクタの直後にデータのロードメソッドを呼び出しています。時には、私はこれらの20のフィールドに全くアクセスしないかもしれませんが、私はSQLコールの追加コストを必要としなくても追加しています。だから、私はすべてのプロパティを関連するプライベートプロパティを持つように変更し、プログラムがpublicプロパティを呼び出すとプライベートプロパティをチェックし、nullの場合はSQLからデータをロードする必要があるのでロードメソッドを呼び出します。それは素晴らしい動作しますが、私はコードを参照すると、ヌルチェックの繰り返しパターンがあり、SQLクエリをロードします。これを行うより良い方法はありますか?遅延ロードを行うためにプライベートプロパティのヌルチェックを避けるにはどうすればよいですか?

+2

あなたは20回の呼び出しに対して1回のデータベース呼び出しを行ったようですが、平均でアクセスしても6〜8の値でも効果があると思いますか? – V4Vendetta

+1

@ V4Vendettaいいえ、彼は遅延ロードパターンを実装しています。彼のコメントは、ANYプロパティーが初めて呼び出されたときにすべてのプロパティーをロードすると述べています。その後の呼び出しではチェックはfalseになり、メモリー内の値のみが返されます。 –

+0

コンストラクターとバインド・データで一度チェックすることもできます。 –

答えて

4

いいえ、これは正しいです。 Here is the wikipedia article。ヌル・チェックのオーバーヘッドは、不要なデータベース・コールに比べて非常に少なくなります。今、プログラムのユーザーが実際に時間の99%の値を使用している場合、私はこのパターンが必要ではないと言います。

単なる注意点:値がnullの可能性がある場合は、不要なデータベース呼び出しを行います。 (それがちょうどビットのチェックであることからも、迅速にチェックされます)、このような何かをした方がよいかもしれません:

//Constructor default to not loaded 
bool isLoaded = false; 

private string _name; 
public string Name 
{ 
    get { 
     if (!isLoaded) 
     LoadData(); //this popultes not just but all the properties 
     return _name; 
    } 
} 

private LoadData() 
{ 
    //Load Data 
    isLoaded = true; 
} 
+0

匿名のdownvoterに、あなたはなぜあなたがdownvotedあなたが戻ってこれを見ている機会がない場合は、p) –

+0

私は同様の実装をしていましたが、私はそれが反パターンかもしれないと考えました。私はそれが良い解決策だとうれしいです。私はこれで行くだろう。 – Nair

+0

いいえ、アンチパターンではありません。しかし、私(と他の人)が述べたように。この最小限のオーバーヘッドでも価値があることを確認してください。ユーザーがほぼ常に負荷に当たっている場合は、実際のポイントはありません。喜んで助けてください:) –

0

さてあなたはそれを変更することができます:

if (!initialized) 
    LoadData(); 

そして、あなたの中にLoadDataはtrueに初期化されていますが、実際にはその意味を変更しません。

void EnsureData() 
{ 
     if (!dataLoaded) 
     LoadData(); //this populates all the properties 
} 

public string Name { 
    get { 
     EnsureData(); 
     return _name; 
    } 
} 
0

ことの一つは、その各プロパティは一つだけ追加の呼び出しを含む別の方法にあれば抽出することです。プロパティを使用しない場合、クラスをインスタンス化する理由は何ですか?私はあなたがコンストラクタコードの後に​​SQLを呼び出すのは実際にはもっときれいだと信じていますが、もしあなたがそれを使用しようとしているのであればクラスのオブジェクトを作成するだけです。他のより柔軟な解決策は、LoadDataをパブリックにし、必要に応じてオブジェクトインスタンスから必要に応じて呼び出すことです。

0

私はあなたのアプリケーションの構造を検討すべきだと思う:あなたが行うことができます

+0

OPのプログラムの完全な構造を知らずに、私はあなたが遅延ロードパターンを使用しないようにブランケットステートメントを作ることができないことを知っていません。ほとんどのORM(EFとnHibernateを含む)は、遅延ロードを使用してデータベースへのストレスを削減します。オブジェクトはどのように使用されているかによって異なります。 –

+0

私は彼にレイジーローディングパターンを使わないように言ったとは思わない。私は単に彼に必要に応じてロードを呼び出すように言ったが、もう一度EFリポジトリパターンで遅延ロードを使用しただけです。 – evasilchenko

+0

申し訳ありませんが、あなたの答えを間違って解釈しました。また、あなたが私にタグをつけないと、私はあなたのメッセージの通知を受け取りません。私はちょうどこの1つを確認するために起こった –

0

私はデザインパターンの学習プロセスに入っています。あなたがシングルトンのデザインパターンで試してみることができるデータを一度ロードすれば、私は一つの提案があります。

public class Singleton123 
{ 
    private static readonly string _property1 = ClassLoadData.LoadData(); 

    public static string MyProperty1 
    { 
     get 
     { 
      return _property1; 
     } 
    } 

} 

public class ClassLoadData 
{ 
    public static string LoadData() 
    { 
     // any logic to load data 
     return "test"; 
    } 
} 

コールプロパティこのプロパティは一度だけロードされます

Singleton123 obj = new Singleton123(); 
     string stra = Singleton123.MyProperty1; 
     string strb = Singleton123.MyProperty1; 

次のように。

5

Btw C#はデフォルトのレイジーローダー実装を採用しました。 isSomethingLoadedフラグを提供する代わりに、なぜそれを使用しないのですか? :)

public class Bar 
{ 
    private Lazy<string> _name = new Lazy<string>(() => LoadString()); 

    public string Name 
    { 
     get { return _name.Value; } 
    } 
} 

静的でないLoadStringメソッドの場合、遅延ローダーはコンストラクタで初期化する必要があります。

+0

WOWはC#でLazyが存在することを知らなかったが、それはヌルチェックとロードを行うのだろうか?私はそれを見上げる。それが利用可能な場合は、私たちの代わりに、別のフラグを使用してデータのロードをチェックする必要があります。 – Nair

+0

はい、存在します.Net 4.はい、nullをチェックし、提供されたデリゲートを介して値をロードします。良いニュース - 参照型だけでなく値型も使用できます。 –

+0

こんにちはbwシングルトンのデザインパターンと怠け者は何ですか?私はどちらも同じように思える。 –

関連する問題