[英]LINQ, get string list using dynamic field name
所以我想從表中返回具有唯一值的String類型的List。
值得注意的是,該表的設計者決定該表的每一行都具有多列且具有多個唯一字段。 因此,您不僅可以從表中獲得項目的唯一列表,還需要指定該字段然后變得與眾不同。
因此,為此,我想編寫一個通用方法,在其中可以指定列名稱並獲得唯一的項目列表。
我已經嘗試了以下兩種方法:
retList = context.LP_Specification.Select(x => x.GetType().GetProperty(fieldName).GetValue(x).ToString()).Distinct().ToList();
retList = context.LP_Specification.Select(fieldName)
也行不通。
但是,使用這樣的反射會出現錯誤。
因此,方法調用如下所示:
public List<string> GetSpecs(string fieldName)
我想從表中獲取字符串值的列表,只返回指定字段的不同值。
您不需要使用反射來獲取每個對象的屬性值,因為該查詢將針對數據庫執行,因此該方法將不起作用(除非在查詢內存中的集合的情況下)。
您需要構建動態表達式樹來實現所需的功能。 一個簡單的例子是這樣的:
// Building expression x=> x.FieldName
ParameterExpression foo = Expression.Parameter(typeof(Foo), "x");
MemberExpression selection = Expression.PropertyOrField(foo, "FieldName");
var lambdaExp = Expression.Lambda<Func<Foo, string>>(selection, foo);
用法:
retList = context.LP_Specification.Select(lambdaExp).Distinct();
上面假設實體類型為Foo
並且該屬性稱為"FieldName"
。
您始終可以使用以下方法創建擴展方法:
public static class MyExtensions
{
public static IQueryable<V> SelectByName<T, V>(this IQueryable<T> source,
string FieldName)
{
ParameterExpression paramExp = Expression.Parameter(typeof(T), "x");
MemberExpression memberExp = Expression.PropertyOrField(paramExp, FieldName);
var lambdaExp = Expression.Lambda<Func<T, V>>(memberExp, paramExp);
return source.Select(lambdaExp);
}
}
用法:
retList = context.LP_Specification
.SelectByName<LP_Specification, string>("SomeFieldName").Distinct();
我認為您可以使用如下通用方法:
private IEnumerable<string> GetResult<T>(IEnumerable<T> list, string propName)
{
var retList = new List<string>();
var prop = typeof (T).GetProperty(propName);
if (prop == null)
throw new Exception("Property not found");
retList = list.Select(c => prop.GetValue(c).ToString()).ToList();
return retList;
}
並這樣稱呼它:
var result = GetResult(context.LP_Specification, "FieldName");
如果列數基本上是靜態的,那么您應該可以嘗試一下。 這消除了對反射樹和復雜表達樹的需求;
// this will be used in all querys; add 'where' clauses etc if you want
IQueryable<Specification> rootQuery = from s in specification select s;
IQueryable<string> names = null;
switch(fieldName)
{
case "field1": names = rootQuery.Select(r => r.field1); break;
case "field2": names = rootQuery.Select(r => r.field2); break;
case "field3": names = rootQuery.Select(r => r.field3); break;
default: throw new ArgumentOutOfRangeException("Unknown field: " + fieldName);
}
var strings = names.Distinct().ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.