我想为具有不同IQueryable列表的两个数据表实现服务器端过滤
public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
{
if (name!= null )
query = query.Where( a =>a.name.Contains(name) );
if (number!= null )
query = query.Where( a =>a.number.ToString().Contains(numbr) );
return query;
}
和
public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
{
if (address!= null )
query = query.Where( a =>a.name.Contains(address) );
if (email!= null )
query = query.Where( a =>a.email.Contains(email) );
return query;
}
由于实现方式相同,但是ClassA和ClassB具有不同的属性,涉及不同的检查以搜索值。
如何制作一个通用函数,使我可以同时使用这两个类进行搜索?
答案 0 :(得分:0)
可能的解决方案,使用对象反射。参数有两个成对的字符串。首先是属性的名称,其次是属性的值。
public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string>[] parameters)
{
Type type = typeof(T);
PropertyInfo[] properties = type.GetProperties();
foreach(var parameter in parameters)
{
PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
if (pi != null)
{
query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
}
}
return query;
}
答案 1 :(得分:0)
例如,您可以为同一接口IPropertyWalker创建两个分类。它应该具有字符串索引器。
public string this[string key]
{
switch(key)
{
case "Name"
return Name;
//list all you need for your class
}
}
public string this[string key]
{
switch(key)
{
case "Name"
return Name;
//list all you need for your class
}
}
然后传递属性名称以比较数据。
答案 2 :(得分:-1)
改进@wannadreams响应,仅当目标的成员类型是属性时,才可以查找属性信息。这是一个完整的例子。
class ClassA
{
// Will work
public string Name { get; set; }
// Will not work
public string Name;
}
public static async Task Main(string[] args)
{
IQueryable<ClassA> query = ...
search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
}
public static IQueryable<T> search<T>(
IQueryable<T> query,
params Tuple<string, string>[] parameters)
where T : class
{
foreach(var criteria in parameters) {
var property = typeof(T).GetProperty(criteria.Item1);
if (property == null) continue;
// you also need to verify the property was retrievable from the instance.
query = query.Where(item => property.GetValue(item) != null)
.Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
}
return query;
}