3

少し問題があります。これについて詳しく説明します。

私のシステムでは、EF4.1で動作する汎用リポジトリがあります。すべてが素晴らしい動作をしますが、特定の状況で問題が発生し、いくつかのクエリに対して動的なorderByを実行する必要があります。

orderByを実行するために、クラスのフィールドを表す「文字列」をパラメーターで受け取ります(「id」や「description」など)。

コードの一部:

        public class SomeClass
        {
            public int id { get; set; }
            public string description { get; set; }
        }

        // First we define the parameter that we are going to use
        // in our OrderBy clause. This is the same as "(parameter =>"
        // in the example above.
        var param = Expression.Parameter(typeof(SomeClass), "parameter");

        // Now we'll make our lambda function that returns the
        // request.SortingName property by it's name.
        var expression = Expression.Lambda<Func<SomeClass, int>>(Expression.Property(param, request.SortingName), param);

このコードは、「request.SortingName」が「int」(id)型の場合は機能しますが、「string」(説明)または別の型でorderByを作成する場合は、このコードは機能しません。

式を「オブジェクト」を使用するように変更しました。

        var expression = Expression.Lambda<Func<SomeClass, object>>(Expression.Property(param, request.SortingName), param);

しかし、コードを実行すると、コンパイラは次の例外をスローします。タイプ「System.Int32」の式をリターンタイプ「System.Object」に使用することはできません。

プロパティが文字列型の場合、例外は「System.String」型の式を戻り型「System.Object」に使用できないことです。

つまり、コードは「オブジェクト」タイプでは機能しません。

どうすればこれを理解できるか知っている人はいますか?

御時間ありがとうございます。

4

1 に答える 1

8

EF4と、標準の開発ライブラリで作成したいくつかのジェネリックメソッドを使用して、動的な並べ替えとページ分割を行う方法は次のとおりです。重要なのは、SortByメソッドのLambda式を作成するために使用するコードの2番目のビットです。

public enum SqlOrderByDirecton
{
    ASC,
    DESC
}

 //Derive Lambda Expression from string

 string sortByKey = "BusinessId";
 string value = "DESC";

 var p = Expression.Parameter(typeof(T));

 this.SortBy = Expression.Lambda<Func<T, dynamic>>(Expression.TypeAs(Expression.Property(p, sortByKey), typeof(object)), p).Compile();

 this.SortOrder = (DevCore.SqlOrderByDirecton)Enum.Parse(typeof(DevCore.SqlOrderByDirecton), value, true);

public static List<T> SortAndPaginate<T>(IEnumerable<T> query,
                                             Func<T, object> sortBy,
                                             SqlOrderByDirecton sortOrder,
                                             int rowLimit,
                                             int startRecord,
                                             out int recordCount)
    {
        recordCount = query.Count();

        List<T> list = new List<T>();

        if (sortOrder == SqlOrderByDirecton.ASC)
        {
            list = query.OrderBy(sortBy).Skip(startRecord).Take(rowLimit).ToList();
        }
        else
        {
            list = query.OrderByDescending(sortBy).Skip(startRecord).Take(rowLimit).ToList();
        }

        return list;
    }
于 2012-05-03T01:19:02.853 に答える