2013-05-17 10 views
5

シナリオ:レポート生成を処理するプログラムを作成しています。ドメインとEFに別々のモデルを使用する必要がありますか?

私はEFモデルにマップされたデータベースにレポートを保存しています。非データベースフィールドがいくつかあります(つまり、一部のフィールドは、データベースにある他のフィールドに基づいて自動的に計算されます)。 DBに単独でマップする1つのクラスと、その情報を受け取り、さらに他の計算フィールドを持つ別のクラスを持つことは理にかなっていますか? codefirstデータベースと対話するためのサンプルクラスすなわち

は、それが別のクラスを作るために理にかなって

public class Report{ 
    public int CategoryOneSeverity {get; set;} 
    public int CategoryTwoSeverity {get;set;} 
    public string Title {get;set;} 
} 

だろう、のような:

public class ReportModel{ 
    public int CategoryOneSeverity; 
    public int CategoryTwoSeverity; 
    public string Title; 

    public int RiskRating{ 
     get{ return CategoryOneSeverity + CategoryTwoSeverity; } 
    } 
}  

それともRiskRatingプロパティはEFにする必要がありますモデル。

+0

私は、別々のクラス(データストアをモデル化するモデルとビジネスドメインをモデル化するモデル)を用意しなければならないという受け入れられた答えに同意します。しかし、2番目のクラスはいくつかの優れた設計公理に違反しています。最も顕著なのは、フィールドが公開されてはならないということです。 –

+0

私は実際にプライベートメンバーを入れてから、それを取得するためにプロパティを使用するのが好きではありません。特に変更が予想される分野では、フィールドがより意味をなさないか?すなわち、ユーザはいつでもタイトルを変更することができる。 – appsecguy

+1

いいえ、実際、それは意味をなさないし、私が言ったように、良いデザインの面で飛ぶ。このプロパティを使用して、検証ロジックを追加し、バッキングフィールドの表現を変換で変更し、最終的に安定した消費者表面積を維持することができます。私たちの良い友達であるJon Skeetがもっとうまくいっているようにしてください:http://www.csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx –

答えて

4

はい、私は絶対にあなたのDBよりもあなたのドメインをモデル化するために異なるクラスを持つべきだと思います。アプリケーションが非常に些細な場合を除き、ドメインオブジェクトを直接マップする場合は、データ構造が必要なものに合わせて変更する必要があります。公開したくないものを公開する可能性があります。それを単一責任原則に違反していると考えてください。クラスにドメインオブジェクトを作成して直接マップすると、クラスには2つの理由があります。 1つはビジネス要件の変化に対応し、もう1つはデータストレージスキーマの変更に対応しています。

+0

"あなたのクラスにはドメインオブジェクトを作成し、それを直接マッピングすると2つの理由があります.1つはビジネス要件の変化に対応し、もう1つはデータストレージスキーマの変更に対応するものです。 - それは私を完全に視覚化するのに役立ちました。ありがとう! – appsecguy

4

「それは意味が単独でDBにマップする一つのクラス、およびその情報を受け取り、さらに 他の計算フィールドを持つ 別のクラスを持つようになるだろう?」

はいそうです。私のエンティティクラスがHumanResourcesReportだった場合、通常、私は新しいクラスに "ViewModel"の後ろにHumanResourcesReportViewModelを作成します。

ViewModelsの使い方にはさまざまなバリエーションがありますが、用語についての賢明な議論ができますが、概念的には、エンティティを取り上げて、そのデータとレポートの処理に必要な追加情報を含む新しいクラスを作成します。この場合、レポートの生成はMVCモデルのビューと同じように行われるため、データを保持するクラスをViewModelと呼ぶのは面倒です。

+0

私はあなたが建築のもう一端を話していると思います。すなわちUI。 ViewModelはUIで使用されます。そのため彼らは 'View'モデルと呼ばれています。 –

+1

@Robertレポートの生成は、ビューの最後にあります。データベースからデータを取得し、ViewModelにシェイプしてから、データをプレゼンテーションするレポートを生成します。それがレポートエンジンかhtmlエンジンのどちらで生成されたとしても、それはビューです。あなたはそれがあなたが快適であるものを呼ぶことができますが、概念的には同じことです。エンティティの一部ではない追加データが必要です。 – AaronLS

+0

ああ、私はあなたが意味するものを参照してください。 RiskRatingの計算は、* display *関数です。 –

4

DB Firstのコードファーストを使用していますか?

モデルには、データベースのフィールドにマップされていない自動計算フィールドを含めることができます。

また、アーキテクチャによって異なります。 DBを最初に使用している場合、EFモデルをリフレッシュすると、EFクラスが更新され、マップされたフィールドが失われます。 DB-Firstシナリオでは、EFモデルクラスを基底クラスとして使用し、それをレポートクラス用に継承する方法もあります。

public class ReportModel 
{ 
public int CategoryOneSeverity; 
public int CategoryTwoSeverity; 
public string Title; 
} 

public class ReportClass : ReportModel 
{ 
public int RiskRating 
{ 
get{ return CategoryOneSeverity + CategoryTwoSeverity; } 
} 
} 
+0

これは、ほとんどのアプリケーションではほとんど問題なく動作します。 – Andy

+0

+1また、プロパティをReportModelクラスに直接追加し、 '[NotMapped]'属性でタグ付けすることもできます。あなたに余分なクラスを保存しますが、一方では頻繁に使うことのないプロパティでエンティティクラスを混乱させます。それで、あなたがどのように行くのかを判断するコールが少しあります。 – AaronLS

+0

Andy:多くの情報はありませんでしたが、完全に機能するソリューションではなく、提供された情報で何が達成できるかを示すことを目的としていました。 –

関連する問題