を返すだけIQueryable<T>
です。
別の「リポジトリ コード」を作成する前に、Ayende の記事Architecting in the Pit of Doom - The Evils of the Repository Abstraction Layerを読むことで大きなメリットが得られます。
あなたのアプローチは、間違いなく、不必要な複雑さを大幅に追加しています。
Generic List of OrderBy Lambdaの他の質問のすべてのコードは、既存の有効な API を不必要で見慣れない抽象化でマスクする以外に何もしていません。
お二人の懸念事項について、
LINQ プロバイダーの動作は異なりますが、渡す述語を LINQ プロバイダーで処理できる限り、これは関係ありません。そうしないと、最終的にExpression
に渡される を渡しているため、同じ問題が引き続き発生します。実装が述語を処理できないIQueryable
場合、述語を処理できません。(翻訳できないさらなるフィルタリングの前に評価する必要がある場合はIQueryProvider
、いつでも a を呼び出すことができます)。ToList()
クエリを変更するとパフォーマンスの問題が発生する可能性がありますが、必要な機能が公開される可能性が高くなります。さらに、最適化されていない LINQ クエリによって発生するパフォーマンスの問題は、データ アクセス ロジックの露出を避けるために必要以上に多くのレコードを取得しIQueryable
たり、肥大化したデータ アクセス ロジックを体系的にフィルタリングしたりすることによって発生するパフォーマンスの問題よりも、悪影響が少ない可能性があります。実際には何もしない抽象化のレベル (最初の脅威はより重大です)。一般に、ほとんどの主要な LINQ プロバイダーは変換プロセスでクエリ ロジックを最適化するため、これは問題になりません。
クエリ ロジックをフロント エンドから隠したい場合は、汎用リポジトリを作成しないでください。実際のビジネス固有のメソッドでクエリをカプセル化します。さて、私は間違っているかもしれませんが、リポジトリ パターンの使用はドメイン駆動設計に触発されていると想定しています。この場合、リポジトリを使用する理由は、ドメイン モデルに重点を置いて永続性を無視したドメインを作成できるようにするためです。ただし、この種の汎用リポジトリを使用しても、セマンティクスが からCreate Read Update Delete
に変更されるだけFind Add Remove Save
です。そこに組み込まれている実際のビジネス知識はありません。
の意味 (および使いやすさ) を考慮してください。
interface IPersonRepository
{
Person GetById(int id);
IEnumerable<Person> FindByName(string firstName, string lastName);
}
とは対照的に
interface IRepository<T> {
IEnumerable<T> FindBy(Query<T> query);
}
IRepository<T>
さらに、 ( ではなく)を使用する利点を実際に指摘できますIQueryable<T>
か?
また、一般的なアプローチでは、実際にはクエリ ロジックをまったくカプセル化していないことを考慮してください。外部でビルドすることになり、不要なコードがさらに増えることになります。
* を使用しないようにアドバイスするリソースに関するもう 1 つの注意事項IQueryable<T>
は、その発行日を確認する価値があるということです。LINQ プロバイダーの可用性がかなり制限されていた時期がありました (初期の EF および LINQ-to-SQL まで)。その時点で を公開するIQueryable<T>
と、Microsoft ORM のより一般的な代替手段の一部との非互換性が伴います (LINQ-to-NHibernate はかなり前に実装されています)。現時点では、本格的な ORM .NET ライブラリでは LINQ サポートが事実上どこにでもあります。