要搜索的 Linq 查询
本文关键字:查询 Linq 搜索 | 更新日期: 2023-09-27 18:31:27
我有一个员工类的集合,员工类有几个属性,如部门,经理姓名,工资等级,称号等。现在在我的webapi中,我有一个搜索方法,我可以在webapi的所有字段中搜索一个字符串
就像如果我搜索彼得一样,它会搜索所有员工的所有字段(部门、manager_name、薪级、指定)。为此,我在下面使用:-
public IEnumerable<Employee> Search(string searchstr)
{
if (repository != null)
{
var query =
from employees in repository.GetEmployees()
where
(employees.departement != null && employees.departement.Contains(searchstr)) ||
(employees.payscale != null && employees.payscale.Contains(searchstr))
(movie.designation != null && movie.designation.Contains(searchstr)) )
select employees;
return query.AsEnumerable().OrderBy(c => c.employeeid);
}
else
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
虽然我得到了想要的结果,但我不必使用该查询。还有其他方法可以重写相同的查询吗?
如 Noctis 所述,使用反射会导致 .NET 运行时的繁重任务。
下面是一些示例代码,它遍历类的所有属性并搜索字符串关联。它使用反射;)
有任何问题,请发表评论询问!
APP入口点中的代码:
[STAThread]
private static void Main(string[] args)
{
var person1 = new Person {Name = "The first name", Address = "The first address"};
var person2 = new Person {Name = "The second name", Address = "The second address"};
var results = SearchStringTroughAllProperties("second", new List<Person> {person1, person2});
}
Person
类:
class Person
{
public string Name { get; set; }
public string Address { get; set; }
}
而SearchStringTroughAllProperties
方法:
private static IEnumerable<Person> SearchStringTroughAllProperties(string stringToSearch,
IEnumerable<Person> persons)
{
var properties =
typeof (Person).GetProperties()
.Where(x => x.CanRead && x.PropertyType == typeof (string))
.Select(x => x.GetMethod)
.Where(x => !x.IsStatic)
.ToList();
return persons.Where(person =>
properties.Select(property => (string) property.Invoke(person, null) ?? string.Empty)
.Any(propertyValueInInstance => propertyValueInInstance.Contains(stringToSearch)));
}
请注意:
- 它在属性中搜索,而不是在字段中搜索
- 它只搜索可以读取的属性(定义了一个)
- 它只搜索字符串类型的属性
- 它仅搜索不是类的静态成员的属性
编辑:
要在 string
或 string[]
属性中搜索字符串重合,请将SearchStringTroughAllProperties
方法更改为以下内容(它变得更长!
static IEnumerable<Person> SearchStringTroughAllProperties(string stringToSearch, IEnumerable<Person> persons)
{
var properties =
typeof (Person).GetProperties()
.Where(x => x.CanRead && (x.PropertyType == typeof (string) || x.PropertyType == typeof(string[])))
.Select(x => x.GetMethod)
.Where(x => !x.IsStatic)
.ToList();
foreach (var person in persons)
{
foreach (var property in properties)
{
bool yieldReturned = false;
switch (property.ReturnType.ToString())
{
case "System.String":
var propertyValueStr = (string) property.Invoke(person, null) ?? string.Empty;
if (propertyValueStr.Contains(stringToSearch))
{
yield return person;
yieldReturned = true;
}
break;
case "System.String[]":
var propertyValueStrArr = (string[]) property.Invoke(person, null);
if (propertyValueStrArr != null && propertyValueStrArr.Any(x => x.Contains(stringToSearch)))
{
yield return person;
yieldReturned = true;
}
break;
}
if (yieldReturned)
{
break;
}
}
}
}
虽然工作,感觉有点脏。我会考虑使用反射来获取类的属性,然后动态搜索它们。
好处是:如果您明天添加新属性,则无需更改任何其他内容。
缺点是:可能没有那么高的性能,因为反射比简单地搜索你知道存在的东西要慢得多。
话虽如此,我相信还有其他一些漂亮的高级 linq 技巧,也许其他人可以指出。
- 使用反射访问属性(C# 和 Visual Basic)
以为我有一些方便的代码,但我没有。我不想把它写在我的头顶上,因为它可能不会编译(你需要正确语法)。看看上面的链接:)