ここにはいくつかの問題があります。
1 つ目は、ToList() が Where 句に一致するすべてのアイテムをデータベースから返すことです。ToList() を実行して、クエリをすぐに実行することはできません。
第二に、あなたは戻ってきていますIEnumerable<ItemModel>
。IEnumerables もクエリをすぐに実行します。IQueryable<ItemModel>
返された型に追加のパラメーターを追加する場合は、を返す必要があります。
第 3 に、Constructor 引数を使用してこれを機能させるのは難しい場合があります。これは、データベースではなくコードで処理する必要があるためです。 テストはできませんが、@dasblinkenlight のソリューションが機能する可能性があります。彼は自分が何を話しているのか知っていると思います。
彼のコードを次のように変更する必要があります。
public IQueryable<ItemModel> GetAll()
{
return this.DataLayer.GetNewsItems()
.Where(i => i.IsActive)
.Select((v,i) => new ItemModel(i));
}
編集:
投影された型にコンストラクター引数を使用することを主張する場合は、フィルターをメソッドに渡すなど、どこかで妥協する必要があります。
このようなもの:
public IEnumerable<ItemModel> GetItemsByDate(DateTime date)
{
return this.DataLayer.GetNewsItems()
.Where(i => i.IsActive && i.Date == date)
.AsEnumerable()
.Select(x => new ItemModel(x));
}
これにより、メソッドを呼び出すときに引き続きクエリが実行されます (出力にこれ以上フィルターを適用してデータベースで実行することはできません) が、IsActive および Date フィルターに一致するオブジェクトのみが返されます。
次のような任意の式を適用することもできます。
public IEnumerable<ItemModel> GetItemsByDate(Expression<Func<SomeWeirdItemModel,bool>> filter)
{
return this.DataLayer.GetNewsItems()
.Where(i => i.IsActive && filter)
.AsEnumerable()
.Select(x => new ItemModel(x));
}
次に、これを簡単に行うことができます:
var items = DataLayer.GetAll(x => x.Date == date);
var others = DataLayer.GetAll(x => x.Date == date && x.Title.Length > 5 && x.Test = "X");
// etc..
残念ながら、式でフィルター処理する必要があるため、パラメーターで SomeWeirdModel を公開する必要があります。そうしないと、フィルターを試して変換するために多くの作業を行う必要があります。