2

DAL から返された DTO があります。例えば

public class CustomerDTO
{
    public int CustId {get; set; }
    public int CustType {get; set; }
    .
    . 
    .
    public string GetCustomerTypes{
      get {  if (CustType== 1) 
               return "Special Customer";
             else if(CustType==
}

現在、クラスに複数のプロパティがあり、これらはどのテーブルにもリンクされておらず、CustId などの属性を表すコードにすぎません (1 =「特別な顧客」、2 =「デフォルト」または 3 =「新規顧客」)。次に、それらの属性を DTO に表示する必要があります。

上記で行ったように、ビジネス ロジックを SQL ステートメントまたは DTO クラスに埋め込むことができます。ただし、さまざまな列に対して、多くの条件付きロジックが必要になります。また、別の DTO を作成する場合は、この条件付きロジックが再び繰り返されます。

クラス設計でこのロジックをカプセル化し、繰り返しを避けるにはどうすればよいですか?

4

4 に答える 4

2

特定のロジックが繰り返される場合は、別のメソッドに配置する必要があります。メソッドの配置はシステムの構造によって異なりますが、一般的に次の 3 つの主要なオプションがあります。

  • ロジックをヘルパー クラスに入れる
  • ロジックを基本クラスに入れる
  • ロジックを拡張メソッドに入れる

最初のオプションは最も単純で、最小限の変更が必要です。次のように、静的メソッドを使用してクラスを追加するだけです。

static class DtoHelper {
    public static string GetCustomerType(int type) {
        ... // Custom logic goes here
    }
}

2 番目の方法は、DTO が共通のクラスを継承する必要があるため、柔軟性が最も低くなります。

class WithCustomerType {
    private int custType;
    public string CustomerType {
        get {
            ... // Custom logic goes here
        }
    }
}
public class CustomerDTO : WithCustomerType {
    ...
}

3 番目のオプションは、型の代わりにインターフェイスを使用するため、より柔軟です。

interface IWithRawCustomerType {
    int RawCustomerType {get;}
}
static class DtoExtensions {
    public static string GetCustomerType(this IWithRawCustomerType dto) {
        int type = dto.RawCustomerType;
        ...
    }
}
class CustomerDTO : IWithRawCustomerType {
    ...
}
于 2013-02-27T11:40:38.840 に答える
1

クラスを部分的にして、部分的なクラスに追加のロジックを書くことができます。すべてのDTOに共通している場合は、その追加のロジックを基本クラスに配置し、DTO用に作成するすべての部分クラスで継承できます。

タイプを文字列に「変換」する際の問題については、列挙型CustomerTypeを定義し、各値のカスタム属性に必要なテキストを設定するだけです。そうすれば、共通のロジックは、各エンティティにあるTypeプロパティの属性値を返すことです。

このようなもの:enum属性からenumを取得します

したがって、あなたの例では、列挙型を定義します。

public enum CustomerType
{
[Tag("SpecialCustomer")]
SpecialCustomer = 1,
...
}

次に、部分クラスで(エンティティが生成されたコードの場合)、デフォルトのメンバーを次のようなプロパティにラップします。

public string CustomerTypeAsString
{
 get
    { 
        return GetTagValue(CustType);
    }
}
于 2013-02-27T11:35:29.410 に答える
1

これらの値をデータベースに入れることをお勧めします。次のような個別のテーブルを作成できます。

CREATE TABLE CustomerTypes (
    ID INT PRIMARY KEY IDENTITY(1, 1),
    Name VARCHAR(50) NOT NULL
)

または、次のようにタイプコードを含む1つのテーブルを作成できます。

CREATE TABLE ListTypes (
    ID INT PRIMARY KEY IDENTITY(1, 1),
    Name VARCHAR(50) NOT NULL,
    TypeCode CHAR(2) NOT NULL
)

いずれにせよ、データベースからDTOを収集するときは、それらのテーブルに結合してその値を取得します。したがって、1つのテーブルを作成した場合、次のようになります。

SELECT c.*, ct.Name FROM Customer c
    JOIN CustomerTypes ct ON ct.ID = c.CustType

タイプコードでより一般的なテーブルを使用する場合は、次のようになります。

SELECT c.*, lt.Name FROM Customer c
    JOIN ListTypes lt ON lt.ID = c.CustType AND lt.TypeCode = '01'

このアプローチが非常にうまく機能する理由は、文字列値が必要であるが、表示目的でのみ必要であり、今後多くのタイプで必要になるためです。さらに、あなたはすでにエンティティを取得しているデータベースにいるので、データベースにこの作業をさせてください。最後に、これらの値をコンボボックスに一覧表示してユーザーに選択させたい場合は、静的ではなくデータベースからそのコンボボックスをバインドできます。

しかし、要するに、これにより、アプリケーションの変更と拡張がはるかに簡単になります。

于 2013-02-27T11:36:11.827 に答える
1

拡張メソッドはどうですか

 public static  class DerivedValues
 {
     public static void ToCustomerTypes(this CustomerDTO dto)
     {
             if (dto.CustType == 1)
             dto.GetCustomerTypes = "Special Customer";
     }
 }

主な用途

var c1 = new CustomerDTO();
        c1.ToCustomerTypes();
于 2013-02-27T11:45:23.110 に答える