ここでポインタと情報を探しています。正しい答えが 1 つもないと思われるので、この CW を作成します。これは C# 用であるため、以下で Linq を参照します。また、長文失礼いたしました。ここで質問を要約させてください。その後、完全な質問が続きます。
概要: UI/BLL/DAL/DB の 4 層アプリケーションで、ユーザー インターフェイスを変更して、より多くの列 (グリッドなど) を表示し、ビジネス ロジック層からデータ アクセス層へのリークを回避するにはどうすればよいでしょうか。表示するデータを取得します (既にデータベースにあると仮定します)。
3(4) 層の階層化されたアプリケーションを想定してみましょう。
- ユーザー インターフェイス (UI)
- ビジネス ロジック層 (BLL)
- データ アクセス層 (DAL)
- データベース(DB;第4層)
この場合、DAL は SQL ステートメントを作成し、データベースに対して実行してデータを返します。
そのようなレイヤーを「正しく」構築して常に「select *」を実行する唯一の方法はありますか? 私にはそれは大したことではありませんが、なぜ私が疑問に思っているのかを説明させてください.
UI に、有効な雇用記録を持つすべての従業員を表示したいとしましょう。「アクティブ」とは、雇用記録の from-to の日付に今日が含まれていることを意味します (または、ユーザー インターフェイスで設定できる日付も含まれている可能性があります)。
この場合、これらすべての人に電子メールを送信したいとします。そのため、BLL には、同じ人にまだ電子メールを送信していないことを確認するコードがあります。
BLL の場合、最小限のデータが必要です。おそらく、データ アクセス層を呼び出してアクティブな従業員のリストを取得し、次に、送信した電子メールのリストを取得する呼び出しを呼び出します。次に、それらを結合して新しいリストを作成します。おそらく、これはデータ アクセス層の助けを借りて行うことができますが、これは重要ではありません。
重要なことは、ビジネス層にとって必要なデータはそれほど多くないということです。おそらく、両方のリストの各従業員の一意の識別子が必要であり、一致してから、「これらはアクティブで、まだメールを送信していない従業員の一意の識別子です」と言うだけです。次に、ビジネス層が必要とするものだけを取得する SQL ステートメントを構築する DAL コードを構築しますか? すなわち。「SELECT id FROM employees WHERE ...」だけですか?
では、ユーザー インターフェイスはどうすればよいでしょうか。ユーザーにとっては、メールを送信する理由に応じて、より多くの情報を含めることがおそらく最善でしょう。たとえば、基本的な連絡先情報、勤務先の部署、マネージャーの名前などを含めたいと思うかもしれませんが、少なくとも名前と電子メール アドレスの情報を表示することは言うまでもありません。
UI はそのデータをどのように取得しますか? UI に十分なデータを返すように DAL を変更する必要がありますか? BLL を変更して、UI に十分なデータが返されるようにする必要がありますか? DAL から BLL に返されたオブジェクトまたはデータ構造を UI にも送信できる場合、おそらく BLL はあまり変更する必要はありませんが、UI の要件は、通信する必要があるレイヤーを超えてレイヤーに影響を与えます。 . また、2 つの世界が異なるデータ構造で動作する場合は、おそらく両方に変更を加える必要があります。
そして、UI が変更された場合、さらに列を追加してユーザーをさらに支援するには、UI を変更するためにどのくらい深くする必要がありますか? (データがデータベースに既に存在すると仮定しているため、そこで変更する必要はありません。)
出てきた 1 つの提案は、Linq-To-SQL と IQueryable を使用することです。これにより、何 (データの種類など) と理由 (WHERE 句など) を処理する DAL が IQueryable を返した場合、BLL はUI にそれらを返す可能性があり、必要なデータを取得する Linq クエリを作成できます。ユーザー インターフェイス コードは、必要な列を取得できます。IQuerables を使用すると、UI が実際にクエリを実行し、「select new { X, Y, Z }」を使用して必要なものを指定し、必要に応じて他のテーブルに結合できるため、これは機能します。
これは私には面倒に見えます。Linq フロントエンドの背後に隠されている場合でも、UI が SQL コード自体を実行すること。
ただし、これを行うには、BLL または DAL がデータベース接続を閉じることを許可しないようにする必要があります。また、IoC タイプの世界では、DAL サービスは UI コードが望むよりも少し早く破棄される可能性があります。 Linq クエリは、「破棄されたオブジェクトにアクセスできません」という例外で終了する場合があります。
だから私はポインタを探しています。私たちはどれくらい離れていますか?これにどう対処していますか?UI の変更が BLL を介して DAL に漏れるという事実は、非常に悪い解決策だと思いますが、今のところ、改善できるようには見えません。
私たちがどれほど愚かであるか教えてください。私が間違っていることを証明してください。
また、これはレガシー システムであることに注意してください。データベース スキーマの変更はまだ何年も前から行われていないため、「select *」と本質的に同等の処理を行う ORM オブジェクトを使用するソリューションは、実際にはオプションではありません。レイヤーのリスト全体をプルアップしたくない大きなテーブルがいくつかあります。