簡體   English   中英

在C#中的通用變量中動態注入類型

[英]Dynamically inject a type in a generic variable in C#

假設我有如下字典。

Dictionary<string, Expression> expressions = new Dictionary<string, Expression> { 
    { "Price", (Expression<Func<Phone, double>>) (p => p.Price) },     
    { "Brand", (Expression<Func<Phone, string>>) (p => p.Name) }     
    };

使用實體框架,我可以獲得如下所示的結果數據。

BdPhonesDbEntities db = new BdPhonesDbEntities();
IQueryable<Phone> phones = db.Phones.Where(search.GetExpression());

現在,根據用戶的選擇,我想按價格(兩倍)或名稱(字符串)對結果進行排序。 使用固定類型(雙精度)進行排序時,如下所示。

    Expression<Func<Phone, double>> keySelector =  
KeySelector<Func<Phone, double>>(expressions, search.OrderBy.PropertyName);            

現在,我想在“ double”位置動態插入類型,而不是僅針對double類型排序進行修復。 是否可以有條件地更改此代碼的排序?

要一目了然地了解總代碼,請檢查以下圖片或來自Gist

在此處輸入圖片說明

對該函數的調用如下所示:

在此處輸入圖片說明

試試這個實用工具類https://dotnetfiddle.net/T9CFYU

public static class Utility
{
    public static Expression<Func<TSource, object>> GetExpressionForProp<TSource>(this TSource source, string propertyName)
    {
        var param = Expression.Parameter(typeof(TSource), "x");
        Expression conversion = Expression.Convert(Expression.Property(param, propertyName), typeof(object));
        return Expression.Lambda<Func<TSource, object>>(conversion, param);
    }

    public static IOrderedQueryable<TSource> OrderByProp<TSource>(this IQueryable<TSource> source, string propertyName) 
        where TSource : class, new()
    {
        return source.OrderBy(new TSource().GetExpressionForProp(propertyName));

        //or comment where TSource : class, new() and
        //var param = Expression.Parameter(typeof(TSource), "x");
        //Expression conversion = Expression.Convert(Expression.Property(param, propertyName), typeof(object));
        //var shortExpression = Expression.Lambda<Func<TSource, object>>(conversion, param);
        //return source.OrderBy(shortExpression);
    }
}

一些用法,例如

List<Phone> orderedByPrice = null;
List<Phone> orderedByBrand = null;

/*Try: 1*/
orderedByPrice = Db.Phones.OrderBy(new Phone().GetExpressionForProp("Price")).ToList(); 
orderedByBrand = Db.Phones.OrderBy(new Phone().GetExpressionForProp("Brand")).ToList(); 

/*Try: 2*/
orderedByPrice = Db.Phones.OrderByProp("Price").ToList();
orderedByBrand = Db.Phones.OrderByProp("Brand").ToList();

/*Try: 3*/
var expressions = new Dictionary<string, Expression<Func<Phone, object>>>
{
    {"Price", (p => p.Price)},
    {"Brand", (p => p.Brand)}
};
orderedByPrice = Db.Phones.OrderBy(expressions["Price"]).ToList();
orderedByBrand = Db.Phones.OrderBy(expressions["Brand"]).ToList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM