0

Linq を使用してフィルター処理し、リストに変換する方法がありますが、要求された呼び出しの早い段階でリストに変換されます。ここでカスタム メソッドの例を参照してください。

public IEnumerable<ItemModel> GetAll()
{
    var output = new List<ItemModel>();

    this.DataLayer.GetItems() //returns IQueryable<SomeWeirdItemModel>
        .Where(i => i.IsActive == true) 
        .ToList()
        .ForEach(i => output.Add(new ItemModel(i)));

    return output;
}

問題は、私が行うときですthis.GetAll().Where(i => i.StartDate >= DateTime.Now)。私のカスタムメソッドは、データベースからすべてを取得するリストに変換し、リクエストを日付でフィルタリングします。呼び出された Linq を取得してカスタム メソッドに実装するにはどうすればよいですか?

このようなもの? this.DataLayer.GetNewsItems().Where(i => i.IsActive == true && (REQUESTED FILTER HERE?))

4

1 に答える 1

2

ここにはいくつかの問題があります。

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 を公開する必要があります。そうしないと、フィルターを試して変換するために多くの作業を行う必要があります。

于 2013-06-24T23:56:51.933 に答える