3

おそらく単純な 3 層の問題です。これにはベスト プラクティスを使用するようにしたいだけですが、私はまだ構造に精通していません。

3 つの層があります。

  • GUI: プレゼンテーション層用 ASP.NET (最初のプラットフォーム)
  • BAL: ビジネス レイヤーは C# で Web サーバー上のロジックを処理するため、両方とも Web フォーム/MVC + Web サービスに使用できます。
  • DAL: データ層の LINQ to SQL。LINQ ではなく BusinessObjects を返します。
  • DB: SQL は Microsoft SQL-server/Express になります (まだ決定していません)。

[Persons] のデータベースがある設定を考えてみましょう。それらはすべて複数の [Address] を持つことができ、すべての [PostalCode] と対応する都市名などの完全なリストがあります。

取り決めは、他のテーブルから多くの詳細を結合したことです。

{リレーション}/[テーブル]

  • [人]:1 --- N:{人の住所}:M --- 1:[住所]
  • [住所]:N --- 1:[郵便番号]

次に、Person 用の DAL を作成します。PersonBO はどのように見えるべきで、結合はいつ行われますか? すべての都市名と可能な住所を取得するのはビジネス層の問題ですか? 人?または、PersonBO を BAL に返す前に、DAL がこれをすべて完了する必要がありますか?

Class PersonBO 
{
    public int ID {get;set;}
    public string Name {get;set;}
    public List<AddressBO> {get;set;} // Question #1
} 

// Q1: PersonBO を返す前にオブジェクトを取得し、代わりに配列にする必要がありますか? または、これはn層/ 3層では完全に間違っていますか??

Class AddressBO 
{
    public int ID {get;set;}
    public string StreetName {get;set;}
    public int PostalCode {get;set;} // Question #2
} 

// Q2: 検索を行いますか、それとも PostalCode を後で検索するために残しますか?

どのオブジェクトをどの順序でプルするかを誰か説明できますか? 建設的な批判は大歓迎です。:o)

4

1 に答える 1

2

あなたは車輪の再発明のようなものです。ORM はすでにこの問題のほとんどを解決しており、自分で行うのは少し難しいと感じるでしょう。

Linq to SQL、Entity Framework、NHibernate などの ORM がこれを行う方法は、関連付けの遅延読み込みと呼ばれる手法です (オプションで熱心な読み込みでオーバーライドできます)。

をプルアップするPersonと、具体的に要求するまでロードされませんAddress。その時点で、データベースへの別のラウンドトリップが発生します (遅延ロード)。クエリごとに、すべてのAddress人にロードするように指定することもできます(イーガー ロード)。

AddressBOある意味では、この質問では基本的に、 の遅延読み込みまたは熱心な読み込みを実行する必要があるかどうかを尋ねていますがPersonBO、答えはどちらでもありません。普遍的に機能する単一のアプローチはありません。 デフォルトでは、不要な結合を大量に行わないように、おそらく遅延読み込みを行う必要があります。PersonBOこれを実現するには、DAL への参照を維持する遅延読み込みメカニズムを使用してビルドする必要があります。ただし、「ビジネス アクセス」ロジックに組み込む必要がある、eager-load のオプションが必要な場合もあります。

多くの異なるテーブルから特定のプロパティが取り込まれた、高度にカスタマイズされたデータ セットを返す必要がある場合の別のオプションは、 をまったく返さずPersonBOに、代わりにデータ転送オブジェクト(DTO) を使用することです。デフォルトの遅延読み込みメカニズムを実装する場合、これを熱心な読み込みバージョンとして置き換えることができる場合があります。


参考までに、データ アクセス フレームワークの遅延ローダーは、通常、関連付け自体に読み込みロジックを使用して構築されます。

public class PersonBO
{
    public int ID { get; set; }
    public string Name { get; set; }
    public IList<AddressBO> Addresses { get; set; }
}

これは単なる POCO です。魔法は実際のリストの実装で起こります。

// NOT A PRODUCTION-READY IMPLEMENTATION - DO NOT USE

internal class LazyLoadList<T> : IList<T>
{
    private IQueryable<T> query;
    private List<T> items;

    public LazyLoadList(IQueryable<T> query)
    {
        if (query == null)
            throw new ArgumentNullException("query");
        this.query = query;
    }

    private void Materialize()
    {
        if (items == null)
            items = query.ToList();
    }

    public void Add(T item)
    {
        Materialize();
        items.Add(item);
    }

    // Etc.
}

(これは明らかに本番用ではありません。テクニックを示すためのものです。クエリから始めて、必要になるまで実際のリストを具体化しないでください。)

于 2010-06-05T14:15:07.140 に答える