LInq动态组装条件查询,去重
组装条件1 例:s=>s.id=1
/// <summary>
/// 动态组建Linq条件 例如 s=>s.id=1
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Tkey"></typeparam>
/// <param name="propertyName">传入的属性名称</param>
/// <param name="Value">传入的属性值</param>
/// <returns></returns>
public static Expression<Func<T, Tkey>> WhereData<T, Tkey>(string propertyName, object Value)
{
Type cType = typeof(T);
ParameterExpression paramEx = Expression.Parameter(cType, "s");
Expression equal = Expression.Property(paramEx, cType, propertyName);
Expression right = Expression.Constant(Value);
Expression fi = Expression.Equal(equal, right);
Expression<Func<T, Tkey>> lambda = Expression.Lambda<Func<T, Tkey>>(fi, paramEx);
return lambda;
}
使用
class Program
{
static void Main(string[] args)
{
var res = new List<CorrespondingDataModel>()
{
new CorrespondingDataModel(){ A=1,B=2,C=3},
new CorrespondingDataModel(){ A=1,B=3,C=2},
new CorrespondingDataModel(){ A=2,B=1,C=3}
};
if (res != null && res.Any())
{
//下面2种都可以
//var obj = res.AsQueryable().Where(LinqUntil.WhereData<CorrespondingDataModel, bool>("A", 1)).ToList();
var obj = res.AsQueryable().Where(LinqUntil.WhereData<CorrespondingDataModel, bool>(CorrespondingEnum.A.ToString(), 1)).ToList();
//等价于
var obj = res.AsQueryable().Where(s=>s.A==1).ToList();
res.ForEach(s => Console.WriteLine("A:{0},B:{1},C{2}", s.A, s.B, s.C));
}
Console.ReadKey();
}
}
public class CorrespondingDataModel
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
}
public enum CorrespondingEnum
{
A,
B,
C
}
结果:
组装条件2不带值 例:s=>s.id,适用去重
/// <summary>
/// 组建条件,例如 s=>s.id
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Tkey"></typeparam>
/// <param name="propertyName"></param>
/// <returns></returns>
public static Func<T, Tkey> WhereDataNoValue<T, Tkey>(string propertyName)
{
ParameterExpression p = Expression.Parameter(typeof(T), "s");
Expression body = Expression.Property(p, typeof(T).GetProperty(propertyName));
var lambda = Expression.Lambda<Func<T, Tkey>>(body, p);
return lambda.Compile();
}
/// <summary>
/// Linq去重
/// 用法例子:List.AsQueryable().DistinctBy(s => s.要去重的参数).ToList();
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector"></param>
/// <returns></returns>
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
使用
var res = new List<CorrespondingDataModel>()
{
new CorrespondingDataModel(){ A=1,B=2,C=3},
new CorrespondingDataModel(){ A=1,B=3,C=2},
new CorrespondingDataModel(){ A=2,B=1,C=3}
};
//去重,查询 s->s.id
//res = res.AsQueryable().DistinctBy(LinqUntil.WhereDataNoValue<CorrespondingDataModel, int>(CorrespondingEnum.A.ToString())).ToList();
res = res.AsQueryable().DistinctBy(LinqUntil.WhereDataNoValue<CorrespondingDataModel, int>("A")).ToList();
//等价于
res = res.AsQueryable().DistinctBy(s=>s.A).ToList();
res.ForEach(s => Console.WriteLine("A:{0},B:{1},C{2}", s.A, s.B, s.C));
结果:
第二种
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
使用
var query = people.DistinctBy(p => new { p.Id, p.Name });
var query = people.DistinctBy(p => p.Id);