0

リポジトリパターンとViewModelsを使用して、生のデータベースオブジェクトをリポジトリの外部にリークさせたくない場合、データベースに対してどのようにクエリを作成しますか?すべてのデータベースをメモリにロードせず、LINQ to Objectsを使用せずに実際にクエリを作成するにはどうすればよいですか?IQueryableをアプリの残りの部分に公開できません。

たとえば、EFを使用すると、dbフィールドに一致するいくつかのプロパティを持つPOCOがたくさんありますが、N + 1を防ぎ、クエリを簡単にするための外部キーIDだけでなく、(現時点では)直接サポートされていない列挙型を回避するためのいくつかのものもあります。すぐ。それらがアプリケーションの残りの部分に漏れてほしくないので、アプリケーションに通常のオブジェクトグラフだけを表示させたいのです。

public class DbUser
{
    public int Id { get; set; }
    public string Name { get set; }

    public int GroupId { get; set; }
    public DbGroup Group { get; set; }

    public ICollection<DbComment> { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string Name { get set; }

    public Group Group { get; set; }
    public ICollection<Comment> { get; set; }
}

ここでの問題は、私のリポジトリが内部でクエリにEFを使用することです(ユニットテストの場合はメモリ内のもの)。しかし、どうすれば実装できIQueryable<User> FindAll()ますか?戻るだけではいけませんdbContext.Users.Select(u => new User(u))。その場合、考えられるすべてのクエリ機能が失われます。ユーザーコレクション全体をメモリにロードし、すべてのタイプをDbUserからUserに変換してから、メモリ内のコレクションでLINQクエリを構築するだけです。これは非常に非効率的です。

リポジトリにクエリを作成することはできません。一部のページには、いくつかのフィールドを選択するクエリがありますが、他の関連オブジェクトから複雑なものを計算し、結果に基づいてそれらをフィルタリングします(たとえば、正のスコアを持つコメントの数)が、アプリケーションに戻す必要もあります。複雑なものを取得してアプリケーションに返すために使用されるすべてのオブジェクトを選択できますが(dbエンティティとしてではありません)、それは大量のデータを選択することを意味します。

基本的に、リポジトリの外部でクエリを作成する機能を維持しながら、データベースエンティティがアプリケーションの残りの部分を不正やハッキングで汚染するのを防ぐにはどうすればよいですか?

4

1 に答える 1

1

CQRS(Command Query Responsibility Segregation)は、この問題を解決します。'real'モデル、すべてのビジネスルールなどを含むDomainモデル、および基本的に単純なpoco(Viewsで直接使用できる)である'query-ony'モデルがあります。特殊なクエリのみのリポジトリ。

永続性モデル(EFエンティティ)は、dbと「通信」するためにのみ使用され、リポジトリは常にドメイン/アプリケーションオブジェクトを返すか処理します。基本的に、EFエンティティをドメインエンティティにマップする必要があります(保存する場合はその逆)。このようにして、それぞれ独自の目的を持つモデルを分離することができます。

于 2012-07-02T08:24:33.513 に答える