所以我想从表中返回一个唯一值类型的String列表。
值得注意的是,该表的设计者决定表中的每一行都有多个具有多个唯一字段的列。因此,您不能只从表中获取一个唯一的项目列表,您需要指定该字段,然后获得不同的信息。
所以为此,我想编写一个通用方法,我可以在其中指定列名并获取唯一的项列表。
我尝试了下面列出的两种方法;
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)
我想从表中获取字符串值列表,只返回指定字段的不同值。
答案 0 :(得分:3)
您不需要使用反射获取每个对象的属性值,因为此查询将针对数据库执行,以便该方法不起作用(除非在查询内存中的集合中)
您需要构建一个动态表达式树来实现您想要的效果。一个简单的例子就是:
// 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();
答案 1 :(得分:1)
我认为你可以使用这样的通用方法:
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");
答案 2 :(得分:0)
如果列数基本上是静态的,您应该可以试试这个。这消除了对反射和复杂表达式树的需求;
// 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();