2

Ienumerablesはすぐには実行されないことを読んでいます。だから私はリストをクエリするための最良の方法を見つけようとしています。

以下は私のgetAllメソッドです。私のフィルターメソッドが続きます。推奨されるフィルター方法(読みやすさ)が続きます。

私の質問は、3番目の方法は直接クエリを実行するのと同じでしょうか?つまり、DBからすべてのmyObjectをロードしてからフィルタリングするのでしょうか、それともしないのでしょうか。または、DBから取得するときにフィルタリングします。

   public static IEnumerable<myObject> getAll()
    {
        using (var db = Database.OpenConnectionString(blahblah))
        {
            var queryResults = db.Query("SELECT * FROM vu_myObjects");

            return queryResults .Select(x => new myObject(x.myObjectName, x.myObjectF));
        }
    }

    public static IEnumerable<myObject> getAllForFilter(String filter)
    {
        using (var db = Database.OpenConnectionString(blahblah))
        {
            var queryResults  = db.Query("SELECT * FROM vu_myObjects WHERE ObjectF = @0", filter);

            return queryResults.Select(x => new myObject(x.myObjectName, x.ObjectF));
        }
    }

   public static IEnumerable<myObject> getAllForFilter(String filter)
    { // Not checked syntax.
        return getAll().Where(x => x.ObjectF = filter);
    }

あるいは、もっと良い提案があれば、私はすべての耳です。

4

2 に答える 2

3

DBからすべてのmyObjectをロードしてからフィルタリングしますか?

実際にデータベースをまだ照会していないので、そうはなりません。IQueryable<T>したがって、実行を延期しているため、実際に結果セットを返すには、クエリを実行する必要があります。ToListこれは、リストの呼び出しや反復など、いくつかの方法で実行できます。

すべてのフィルタリング、つまりWhere句は、DB側で実行されます。

実際、現在使用しているコードは機能しません。データコンテキストを破棄したObjectDisposedException、遅延クエリにフィルターを適用しようとしているため、がスローされます。コードを機能させるには、メソッドにパラメータとして句を渡す必要があります。wheregetAll

public static IEnumerable<myObject> getAll(Expression<Func<myObject,bool>> where)
{
    using (var db = Database.OpenConnectionString(blahblah))
    {
        var queryResults = db.Query("SELECT * FROM vu_myObjects");
        if (where != null)
        {
            queryResults.Where(where);
        }
        return queryResults .Select(x => new myObject(x.myObjectName, x.myObjectF));
    }
}

public static IEnumerable<myObject> getAllForFilter(String filter)
{ // Not checked syntax.
    return getAll(x => x.ObjectF = filter);
}

アップデート

先ほど指摘したWebMatrix.Databaseように、ここでは実行の遅延が発生しないため、上記のいずれも適用されません。Queryメソッドはすぐに実行され、の結果セットを返すIEnumerable<T>ため、アフターワードに適用されるフィルタリングはすべてメモリ内で実行されます。したがって、効率の観点からは、DB側ですべてを実行するため、最初のフィルター方法の方が適しています。

Where句を実際の文字列に変換してクエリに追加することで、読みやすさと効率の両方を得ることができる場合があります。

于 2013-01-10T11:37:40.523 に答える
2

それらは基本的にすべて同じです。getAlLForFilter呼び出しから返されるIEnumerableに実際に問い合わせるまで、遅延評価されたクエリになります。その上で.ToList()を呼び出すか、コンテンツにアクセスすると、その時点でデータベースが呼び出されます。3番目の呼び出しでブレークポイントを設定すると、デバッガーにクエリを評価するように指示するまで、クエリの結果が含まれないことがわかります。

于 2013-01-10T11:31:35.140 に答える