1

partial classいくつかの派生プロパティを持つように構文を使用して拡張した Entity クラスがあります。これらのフィールドからの情報を使用するインターフェイスを使用してクエリを実行したいのですがIQueryable<T>、現在、次のような例外が発生します。

指定された型メンバー 'Title' は、LINQ to Entities ではサポートされていません。初期化子、エンティティ メンバー、およびエンティティ ナビゲーション プロパティのみがサポートされています。

関連するコード スニペットを次に示します。Entity オブジェクトには という名前の String メンバーがあると想定できますId

public partial class MyEntityObject
{
   public String Title { get { return MyStrings.ResourceManager.GetString(Id) ?? ""; } }
}

/**
 * Throws exception trying to sort on the 'Title' field of a 'MyEntityObject'
 */
public IEnumerable<T> Query<T>(String fieldName, int low, int high)
{
   // Get the ObjectContext<T> using a Repository pattern
   var query = context.GetRepository<T>()

   // Create an OrderBy clause based on the field by dynamically building an expression tree
   //  see http://stackoverflow.com/questions/4546463/help-with-linq-and-generics-using-getvalue-inside-a-query
   PropertyInfo propertyInfo = typeof(T).GetProperty(fieldName);

   ParameterExpression e = Expression.Parameter(typeof(T), "e");
   MemberExpression mexpr = Expression.MakeMemberAccess(e, propertyInfo);

   IQueryable<T> sortedQuery = query.OrderBy(Expression.Lambda<Func<T,Object>>(mexpr, e));
   return sortedQuery.Skip(low).Take(high - low + 1).AsEnumerable();
}

最後の手段として、 andのAsEnumerable()前にいつでも実行できますが、SQL で選択できる場合でも、データベースからすべてのオブジェクトを取得する必要があります。SkipTake

おそらく最良の代替手段は、リフレクションを使用してオブジェクト プロパティが を持っていることを確認してから、または?DataMemberAttributeのいずれかを実行することを選択することです。query.OrderBy().Skip().Take().AsEnumerable()query.AsEnumerable().OrderBy().Skip().Take()

4

1 に答える 1

3

いいえ、できません。linq-to-entities クエリは SQL に変換された式ツリーにすぎないためです。ツリーを SQL に変換するには、エンティティ マッピングが使用さTitleれます。マッピングに含まれていないため、例外がスローされます。

AsEnumerable前にSkipandを呼び出すとTake、データ テーブル全体のコンテンツが常にアプリケーションに転送されるため、非常に悪い設計のように思えます。これは非常に遅くなり、大きなデータ テーブルの場合も役に立ちません。

これがローカライズの問題である場合、これを有効にするには、データベースにローカライズされた文字列が含まれている必要があります。同時に、少数のレコードのみでこれを行う必要がある場合は、それらすべてをロードできます。

于 2011-04-13T19:32:41.733 に答える