データアクセスレイヤー内のビジネスオブジェクト


12

そのため、TDDを介してデータアクセスレイヤーを作成してきましたが、やや懸念がありました。私はむしろ間違った道を進んで行きたくないので、私の考えがきれいなアーキテクチャに沿っているかどうかを確認するように皆さんにお願いしたいと思いました。

私のデータアクセスレイヤー(略してDAL)内のメソッドは非常に単純です。これらはデータベース内のストアドプロシージャと一致しており(これを呼び出して物事をきれいにする方法はありません)、プロシージャと同じパラメータが含まれています。次に、データベースに接続し、クエリ結果を返します。次に例を示します。

public int DeleteRecord(int recordId)
{
    recordId.RequireThat("recordId").NotZeroOrLess();

    List<SqlParameter> parameters = new List<SqlParameter>();
    parameters.Add(new SqlParameter { ParameterName = "@RecordId", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = recordId});

    return this.ExecuteNonQuery("DeleteRecord", parameters.ToArray());
}

私は結果セットで何も意味のあることをしていないので、これはこのタイプのメソッドには完全に機能します。コマンドが機能したことを確認したいだけなので、非クエリの結果、つまり影響を受けた行だけを返し、その番号を使用してロジックを検証できます。

ただし、別のDALメソッドで、レコードをロードしたいとします。マイロード手順が実行されようとしているselectsテーブルの束と戻っに対してDataSet、私はビジネスを作成する必要があり、私のDALは使用方法内のオブジェクトかどうかと戦っていますDataSetまたは私のビジネスオブジェクトの場合自身がちょうど持っている必要がありますLoad()取得するメソッドをDataSetDALから、そして基本的にそれ自身を埋めます。

DALを介してそれを行うと、Business Objectsのロジックが少なくなります(これは単なる選択ロジックですが、それでもロジックです)が、DALを少し混雑させて、本当にすべきでないことをしているように感じさせますやってる

皆さんはどう思いますか?


Entity Frameworkを使用しなかったのはなぜですか?
jfrankcarr

@jfrankcarr-正直に言うと、主に私がそうあるべきほど慣れていないからです。ただし、Entity Frameworkが関係を正しく認識できるように、テーブルを作り直して適切な外部キーなどを追加する必要があります。しかし、好奇心から、私がそれを使用している場合、ビジネスオブジェクト自体でフレームワークを使用してすべての選択を行うだけですか、それともそれらのLINQクエリをどこに置くかについての決定がありますか?

時間をかけてEFを学ぶことをお勧めします。特に、既存の設計上の問題がある既存のデータベースに適合させようとする場合は、最初は少し気が遠くなるかもしれませんが、それだけの価値はあります。
-jfrankcarr

別のオプションを調べたい場合は、NHibernateを調べることもできます。
ドン01001100

@jfrankcarr-間違いなく調べますが、多層データアクセスアプリケーションにどのように適合しますか?エンティティフレームワーク自体は、DAL自体、または別のレイヤー、またはビジネスオブジェクト自体に実装されますか?

回答:


4

DALはデータオブジェクトを返す必要があります

理想的には、DALは「ブラックボックス」オブジェクトである必要があります。これは、アプリケーションコードがデータオブジェクトの要求や既存のデータオブジェクトの操作に使用できるものです。DALとアプリケーションコードの間に別のレイヤーがありRepository、が2つのレイヤーをさらに分離することがありますが、これは必ずしも必要ではありません。

さらに、通常、ビジネスオブジェクトが自分で作成できるようにすることは望ましくありません。これにより、誰かがライブラリを使用できるセキュリティホールが発生し.Load(someId)、それを呼び出すことでオブジェクトの新しいインスタンスを作成し、完全に分離する必要がある2つのレイヤーをマージします。

また.Load(DataSet ds)、データセットの定義が変更された場合、そのデータセットを使用するデータオブジェクトを探し出して変更する必要があるため、メソッドを提供することはお勧めしません。すべてのデータアクセスコードを1か所に保持する方が簡単なので、データアクセスクエリを変更する場合は、DALレイヤーを変更するだけで済みます。


「正しいオブジェクト」の定義が別のレイヤーに保持されている場合、1つのレイヤーが「正しいオブジェクトを返す」ためにどのように依存できるかはわかりません。
TMN

@TMNそれはひどい言葉でした。あなたが正しいので、私は言葉を少し変えました、アプリのコードはどんな種類のオブジェクトがそれを求めているかを知っているべきです。
レイチェル

@レイチェル-ガッチャ。だから、あなたはDALに私のビジネスオブジェクトそのものが正しいもののインスタンスを返すようにすることをお勧めしますか?「データオブジェクト」という言葉に戸惑っていましたが、理解できたと思います。そうすれば、コードを呼び出すだけで、必要な場所からビジネスオブジェクトを要求できます(それ自体ではなく)BusinessObject bo = DAL.LoadRecord(id);。クエリをBO自体にマップするロジックは、DAL内にのみ含まれます。

1
私のようなDAL方法何か名前だろうが、正しいです@Scott Getの代わりにLoadように、Customer c = DAL.GetCustomer(id);
レイチェル

2

私の方法は、LINQ-To-SQLおよびEntity Frameworkの前でさえ、アプリの異なるレイヤー間の通信のための「書面による契約」を提供するインターフェースと抽象クラスライブラリを持つことでした。これは、オントロジー、作業ドメインの定義と呼ばれることもあります。レイヤー間で渡されるものはすべてこの「契約」を使用していました。

生のデータセットオブジェクトをデータレイヤーからビジネスレイヤーに渡すという考えは好きではありません。特にレガシーデータソースを統合する場合、この結果、多くの問題が発生しました。また、プロジェクトに参加する新しい人々がデータの発信元を理解することを非常に困難にする可能性があります。最後に、ビジネスレイヤーがDBから直接データを処理するビジネスに参加している必要があります。これにより、将来的に複雑化する可能性があります。

あなたが持っているサンプルコードは、LINQの前に持っていたコードに似ています。DALオブジェクト内で使用する共通のDB関数クラスがありました。DALクラスはデータを読み取り、それを「契約」オブジェクトに適合させます。削除の例のようなスカラー結果は、値(通常はブール値)を返します。


1
「生のデータセットオブジェクトをデータレイヤーからビジネスレイヤーに渡すという考えが好きではありません。」この。千回、これ。
ジョシュアスミス

@jfrankcarr-私のDALは実際にインターフェースを実装しており、レイヤー間でデータを転送するすべてのもののインターフェースを計画しているので、パターンのアイデアはそこで一致すると思います。ExecuteScalarクエリの直接結果を返すメソッドを、ビジネスレイヤーにとってより意味のある値を返すように変更することをお勧めしますboolか。そうでなければ、これはレイチェルの答えと非常に似ていると思います。

通常、影響を受けるレコードの数が必要でない限り、作成/更新/削除の呼び出しに対してブール値を返します。たとえば、ストアドプロシージャが複数の注文行などを処理している場合、intを返します。
jfrankcarr

0

DALはデータセットを返す必要があります。返されるデータセットはビジネスオブジェクトである必要があります。期待されるデータを持っていることを確認する以外に何もする必要はありません。それをさらに行う必要がある場合は、1つのストアドプロシージャでやりすぎているか、ストアドプロシージャでデータを適切に返していないかのいずれかです。


0

ビジネスオブジェクトには、結果セットからデータを取り込むコンストラクタを用意することをお勧めします。これにより、DALとビジネスレイヤー間の結合が削除されます。2つを完全に分離する場合は、結果セットから列名=>値のペアの単純なマップを作成し、コンストラクターに渡します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.