3

私のWebアプリケーションにアクセスできる会社はいくつかあります。

さまざまな種類の会社:

クライアントサプライヤーエージェント

それぞれがデータベースに独自のテーブルを持ち、メインテーブルCompanyにリンクされています。メインテーブルCompanyは、アドレス、電話、電子メール、TypeOfCompanyなどのすべての一般的なデータを関連するテーブル(クライアントなど)にFKで格納します。

アプリ全体でこのOOを処理するための最良の方法は何ですか?

私は現在次のようなことをしています:

public class CompanyDTO
{
  public int Id {get;set;}
  public string Name {get;set;}
  public Address Address {get;set;}
  public string Type {get;set;} //type of company
  //etc...
}

次に、そのクラスから継承し、追加のプロパティを追加します。

public class ClientDTO : CompanyDTO
{
 public string Key {get;set;}
 public Address Billing {get;set;}
}

しかし、私はそれが時々問題になると感じています

  1. サプライヤーユーザーがアクセスしたい:AllCompanies、-すべての会社のリストを表示
  2. 次に、Supplier Companyのユーザーが特定の会社の詳細を表示したいのですが、それがクライアントの場合、ClientDTOまたはSupplierDTOを表示する必要がありますか?この例では、特定の企業に詳細を示したいと思います

これを処理するための最良の方法は何でしょうか?

たとえばGetCompanyByID(int companyid);GetClientByID(int clientid);両方のインスタンスでクライアントの詳細が必要だと仮定して、両方のインスタンスでどのタイプのオブジェクトを返す必要がありますか。

4

2 に答える 2

3

データベースが派生、集約、カプセル化などのOOプラクティスを理解していないのはおかしいです。これは残念なことに失敗しますが、それでも全体として「データベースインピーダンスの不一致」と呼ばれるものの一部にすぎません。

あなたがやろうとしていることは十分に一般的ですいくつかの解決策があります...

まず、保存するデータモデルの選択があります。基本的に3つの可能性があります。

  1. 行ったようにテーブルを分割します。
  2. 同じテーブル内のすべての派生型のすべてのフィールドを宣言します。
  3. ブロブフィールド(json / xml / whatever)を使用して、一般的でないフィールドを格納します。

次に、データベースからデータを要求するという問題が発生します。これは主に、「共通」ベースタイプのリストの要求と、それらが共有しない非共通フィールドにアクセスする方法を中心にしています。ここでも、いくつかの可能性があります。

  1. 基本タイプをリストすると、それらの共通フィールドのみが返されます。次に、他のフィールドを遅延ロードするために、後続のクエリが1回限り発行されます。
  2. 基本タイプをリストするとき、必要な他のすべてのテーブルもメインテーブルに外部結合され、オブジェクトモデルを完全にインスタンス化するためにすべてのフィールドが使用可能であることを確認します。
  3. 基本タイプを一覧表示すると、結果に必要になる可能性のある「サブタイプ」テーブルごとに1つずつ、複数の結果セットが返されます。次に、クライアントはレコードをつなぎ合わせて、オブジェクトモデルが完成するまで構築します。

網羅的なリストではありませんが、スタートです。個人的には、この理由から、あなたが説明するようなデータモデルは避けたいと思います。基本的に、私の好みは、データモデルですべてのフィールドの結合を定義し(モデル#2)、ビジネスレイヤーを使用して、公開、検証、必須などのプロパティを決定することです。上記のモデル#3も使用しました。複数の値のblobフィールドであり、必要に応じて十分に機能します。モデル#3と#2の唯一の欠点は、これらのフィールドでクエリや並べ替えができないことです。最終的には、どちらのアプローチでも、公開するデータを知るためにビジネスロジックレイヤーが必要です。

データベースは愚かであることを忘れないでください、それらをそのように扱ってください、そしてあなたはうまくやっていくでしょう。(注:このアドバイスは人には効果がなく、データベースだけに効果があります)

于 2011-07-20T21:58:08.893 に答える
1

アクセスしたい:AllCompanies、-すべての会社のリストを表示する

会社のリストが必要な場合、インスタンスが説明する一般的な詳細を求めていませんCompanyDTOか?たぶんあなたのデータアクセス(サービス、リポジトリなど)は次のようになります:

public class CompanyRepository : ICompanyRepository
{
    public IEnumerable<CompanyDTO> GetCompanies()
    {
        // get companies and map them to CompanyDTO objects as necessary
    }
}

それからあなたは尋ねました(まあ、疑問符があります)

次に、特定の会社の詳細を表示したいのですが、それがクライアントの場合、ClientDTOまたはSupplierDTOを表示する必要がありますか?

これは別のビューであるか、少なくとも別の部分的なビューに分割されると思います。ただし、上記の継承について説明したので、表示テンプレートを使用して子タイプの会社を説明することができます。

コントローラーを見せてくれたふりをします。次のようになります。

public class CompanyController : Controller
{
    public ActionResult Details(int id)
    {
        CompanyRepository repo = new CompanyRepository();
        return View(repo.GetCompanyById(id));
    }
}

次に、オブジェクトDetailsを継承する、という名前の強く型付けされたビューを追加し、 :への呼び出しを追加します。CompanyDTOHtml.DisplayForModel()

<%--some scaffolded code ommitted for brevity--%>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.DisplayForModel() %>

</asp:Content>

次に、表示テンプレートの出番です。フォルダを追加します

~/Views/Company/DisplayTemplates

次に、そのフォルダーに3つの強く型付けされ部分ビュー(子タイプごとに1つ)を追加します。Visual Studioは、これを支援します。

  1. フォルダを右クリックDisplayTemplates->[ビューの追加...]
  2. 「ClientDTO」という名前を付けます(これは重要です)
  3. 「部分ビューを作成する」にチェックマークを付ける
  4. 「強い型のビューを作成する」にチェックマークを付ける
  5. ClientDTOクラスを選択します
  6. コンテンツを表示するために選択Detailsします(これにより、自動生成されたマークアップが提供されます)
  7. [追加]をクリックします

他の子タイプに対してこのプロセスを繰り返すと、詳細ビ​​ューに渡されたモデルのタイプに基づいて正しいテンプレートがレンダリングされます。

于 2011-07-20T21:32:27.523 に答える