6

私はここで議論されている方法について知っています:

需要の高いASP.NETWebサイトのLinqtoSqlでコンパイルされたクエリに関する一般的な問題を解決する

...しかし、これは私の状況では機能しません:

「クエリから結果が返された後は、ロードオプションを設定できません。」

Codesmith PLINQOスクリプトを使用してエンティティとマネージャーコードを生成していますが、マネージャーコードは次のようになります。

public partial class SearchManager
{       
    #region Query
    // A private class for lazy loading static compiled queries.
    private static partial class Query
    {
        internal static readonly Func<MyDataContext,IOrderedQueryable<Search>> 
            GetAll = CompiledQuery.Compile(
                (MyDataContext db) =>
                from s in db.Search
                orderby s.Name
                select s);
    } 
    #endregion


    public IQueryable<Search> GetAll()
    {
        return Query.GetAll(Context);
    }
}

最初に、静的DataLoadOptionsを次のようにSearchmanagerクラスにドロップしてみました。

public static readonly DataLoadOptions MyOptions = 
    (new Func<DataLoadOptions>(() =>
    {
        var option = new DataLoadOptions();
        option.LoadWith<Search>(x => x.Rule);
        return option;
    }))();

...次に、次のようにGetAllメソッドのコンテキストに提供します。

public IQueryable<Search> GetAll()
{
    Context.LoadOptions = MyOptions;
    return Query.GetAll(Context);
}

...そしてそれは私が上で述べたエラーを私に与えました。これは、クエリがすでにコンパイルされているため、「余分な」DataLoadOptionsを追加できないためですか?もしそうなら、クエリがコンパイルされる前に、どのようにDataLoadOptionsを適用することが可能でしょうか?

4

4 に答える 4

2

DataContext クラスのセッター プロパティには、DataContext のキャッシュにオブジェクトがあり、LoadOptions が null ではなく、設定しようとしている LoadOptions インスタンスが既に設定されているものと異なるかどうかを確認する条件があります。 、その例外が発生します。

代替#1。クエリごとに新しいコンテキストを作成します (おそらく良い考えではありません)
代替案 #2。リフレクションを使用して ClearCache メソッドを呼び出し、新しい LoadOptions を静的に作成して Context に割り当て、最後にコンパイル済みクエリを取得します。

public partial class SearchManager
{       
    #region Query
    // A private class for lazy loading static compiled queries.
    private static partial class Query
    {
        internal static readonly Func<MyDataContext,IOrderedQueryable<Search>> GetAll 
        {
            get {
                return CompiledQuery.Compile(
                    (MyDataContext db) =>
                        from s in db.Search
                        orderby s.Name
                        select s);
            }
        } 
    #endregion

    public IQueryable<Search> GetAll()
    {
        Context.ClearCache();
        Context.LoadOptions = MyOptions;
        return Query.GetAll(Context);
    }

    public static readonly DataLoadOptions MyOptions = 
        (new Func<DataLoadOptions>(() => MakeLoadOptions<Search>(x=>x.Rule)))();
}

public static class Extensions {
    public static void ClearCache(this DataContext context)
    {
        const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        var method = context.GetType().GetMethod("ClearCache", FLAGS);
        method.Invoke(context, null);
    }

    public static DataLoadOptions MakeLoadOptions<TEntity, TResult>(this Expression<Func<TEntity,TResult>> func) {
        DataLoadOptions options = new DataLoadOptions();
        options.LoadWith(func);
        return options;
    }
}
于 2012-03-05T09:22:03.870 に答える
0
public IQueryable<Search> GetAll() {
     Context.LoadOptions = MyOptions;
     return Query.GetAll(Context);
 } 

Context がすでにクエリ結果を返している場合、この割り当ては遅すぎます。これは、コンパイルされたクエリとは関係なく、すべて DataContext の LoadOptions プロパティの割り当てと関係があります。残念ながら、LoadOptions プロパティのこの動作は msdn に記載されていません。

于 2011-05-24T17:14:08.060 に答える
0

エラーメッセージ自体が、何が間違っているかを正確に示しています。Linq クエリが結果を返した後に DataLoadOptions を適用することはできません。あるいは、次のような言い方がよいかもしれません。DataLoadOptions を適用する場合は、クエリを実行する前に適用してください。後で行うことはできません。

于 2009-12-03T12:32:13.597 に答える
0

コンパイルされたクエリに対してロード オプションを設定できるのは 1 回だけです。2 番目の呼び出しでエラーがスローされている必要があります。割り当てを静的コンストラクターに移動すると、問題が解決するはずです。

于 2010-07-27T14:14:57.323 に答える