0

誰かがこれについていくつかの光を当てることができる場合、少し助けてください。Entity Framework 4.1エンティティ上の緩やかな結合

私はうまく動作しているコード優先のMVC 3アプリケーションを作成しました。私はドメインモデルを後で様々な他のMVC 3アプリケーションで使用したいので、できるだけ多くのカップリングを削除するようリファクタリングしています。私が今持っているのは、正規化されたデータベースを介して永続化され、リポジトリパターンによってCRUDされたエンティティの集合です。私はコントローラのコンストラクタを介してリポジトリをDIにするためにNinjectを使い、MVC 3プロジェクト内のモデルをDAOとして動作させています。

はその後
public class Case : ICase 
{ 
    [Key] 
    public int CaseId { get; set; } 
    public string CaseName { get; set; } 
    public DateTime DateCreated { get; set; } 
    public IClient Client { get; set; } 
} 

私はインターフェイスを持っている(インターフェイスが主に存在する:

ので、ドメイン内の私はと呼ばれるエンティティケース別の場合、このようになりますクライアントへの外部キーを持っていビューモデルに実装してデータアノテーションを追加する方法 - アノテーションをドメインオブジェクトに追加することはできますが、私はこのドメインモデルを異なるユビキタス言語を持つ他のアプリケーションで使用したいと言いました。

public interface ICase 
{ 
    int CaseId { get; set; } 
    string CaseName { get; set; } 
    DateTime DateCreated { get; set; } 
    IClient Client { get; set; } 
} 

そして、私はMVC 3プロジェクト内で私のビューモデルを持っています。

public class CaseModel : ICase 
{ 
    [HiddenInput(DisplayValue = false)] 
    int CaseId { get; set; } 

    [Required(AllowEmptyStrings = false)] 
    [MaxLength(100)] 
    string CaseName { get; set; } 

    [RegularExpression("")] 
    DateTime DateCreated { get; set; }  

    IClient Client { get; set; }  
} 

だから、私の最初の問題はこれです:クライアントにiClientはのための私の外部キー参照を変更すると、新しいものであり、それはNULLオブジェクトを返します。タイプが具体的なクラスだったとき、それはうまく戻りました - これは、EF4.1がIClientのインスタンスを作成しようとしているためです。私はまったく間違っているのですか、これを回避する手段がありますか?

私の2番目の問題(これは私の最初の問題を否定するかもしれません)は、私のドメインエンティティのインターフェースを継承しているビューモデルにデータ注釈を追加することによって何か間違っていますか?モデルのメタデータを使用すべきですか?もしそうなら、メタデータを使ってドメインに触れることなく、データアノテーションを各プロジェクトに固有のものにすることができますか?

ありがとうございます!

+0

なぜ2番目の問題の解決策が私の最初の問題を否定するのかを明確にするだけです。これらのインタフェースが存在する唯一の理由は、ビューモデルがドメインエンティティと同様の構造を持つことです。注釈のメタデータを別のアセンブリにあるドメインエンティティに追加する方が良い場合、これらのインターフェイスは存在する必要はありません。私はそれらを削除し、私のドメインエンティティの具体的なバージョンを使用することに戻ることができます。 –

+1

エンティティのナビゲーション参照にインタフェースを使用することはできません。これは、プロパティに '[NotMapped]属性を入れるのと同じように、EFは単にこのプロパティを無視します。あなたは具体的または抽象クラスを持っていなければなりません。コレクションの場合にのみ、 'ICollection 'のようなインターフェースを使うことができます。一方、 'T'はインタフェースではなくクラスでなければなりません。標準コレクションインタフェースの場合、EFには、 'ICollection -> HashSet 'または 'IList -> List 'などのデフォルトの規則があります。カスタム定義されたインタフェースの場合、EFにはこのようなルールはなく、それらをインスタンス化する方法。 – Slauma

+0

ちなみに、EFは現在4.2までです。 – TrueWill

答えて

3

注意:私はEFまたはMVC3の専門家ではありません。

EFコードファーストエンティティを構築中ですが、エンティティにインターフェイスを追加する予定はありません。リポジトリはインタフェースを取得します。 Units of Workはインターフェイスを取得します。エンティティはしません。リポジトリは、POCOである具体的なエンティティを返します。エンティティは、関連エンティティに結合されてもよい。モデルや他のクラスは通常、リポジトリインタフェースや作業ユニットインタフェースを注入します。テストのために、いくつかのPOCOエンティティを新しく作成し、それらをモックリポジトリから返します。

EFがプロキシを作成できるように、関連するPOCOプロパティを仮想にする予定です。

具体的なエンティティからビューを切り離したい場合は、まずその値からどのような価値が得られるかを尋ねます。ビューは異なるエンティティで再利用される予定ですか?もしそうなら、1つのオプションは、AutoMapperのようなものを使用してプロパティをコピーすることです。しかし、遅延ロードプロパティの即時アクセスに気づく必要があります。

+0

こんにちは、返信ありがとう!私が元のメッセージで伝えようとしたのは、エンティティのインターフェイスが、似たような構造化されたビューモデル(アプリケーション仕様のデータアノテーションを追加する)を持つ目的でのみ存在するということでした。エンティティインタフェースは、デカップリング目的ではまったく存在しません。私の最初の問題は、基本的に私の間違いです。私の実際の質問は、どのようにしてドメインエンティティ(CRUD用)アプリケーションのデータアノテーションを指定し、ドメインにハードコードしないのですか? –

+0

MVC HiddenInputAttributeをエンティティに配置したくないと言っていますが、正しいですか?私はそれに同意するだろう。私はViewModelにそれらを残したいと思います。あなたのエンティティをあなたのViewModelに(手作業またはAutoMapperで)コピーするか、ViewModelをエンティティにデリゲートしてください(より良いかもしれません)。繰り返しますが、私はパターンの専門家ではありません - [ウィキペディアの記事](http://en.wikipedia.org/wiki/Model_View_ViewModel)は代表団を使用しているようです。 – TrueWill

+1

そして、MaxLengthのようなEF固有の属性を意味するならば、私は "どうしたらEFを落とすか他の問題がある"と言うか、Fluent APIを使って別のクラスのマッピングを設定します。 – TrueWill

関連する問題