我有一个集合List<Person> Members
。我需要根据一些标准过滤列表。
请参考以下C#代码:
void Main()
{
List<Person> Members = new List<Person>()
{
new Person() { ID = 101, Name = "Harry", Department = "Testing", Gender = "Male", Role = "Manager"},
new Person() { ID = 102, Name = "Peter", Department = "Development", Gender = "Male", Role = "Manager"},
new Person() { ID = 103, Name = "Emma Watson", Department = "Development", Gender = "Female", Role = "Assistant"},
new Person() { ID = 104, Name = "Raj", Department = "Development", Gender = "Male", Role = "Manager"},
new Person() { ID = 105, Name = "Kaliya", Department = "Testing", Gender = "Male", Role = "Assistant"},
};
}
模型类是:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string Gender { get; set; }
public string Role { get; set; }
}
现在考虑一下情景
场景#1 :使用ID搜索
List<KeyValuePair<string, string>> searchCriteria = new List<System.Collections.Generic.KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("ID", "102")
};
场景#2 :使用ID&amp;搜索系
List<KeyValuePair<string, string>> searchCriteria = new List<System.Collections.Generic.KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("ID", "101"),
new KeyValuePair<string, string>("DEP", "Testing")
};
场景#3 :使用部门,性别和角色进行搜索
List<KeyValuePair<string, string>> searchCriteria = new List<System.Collections.Generic.KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("DEP", "Development"),
new KeyValuePair<string, string>("Gender", "Male"),
new KeyValuePair<string, string>("Role", "Manager"),
};
搜索查询应该像
var iQuery = Members.AsQueryable();
foreach (var item in searchCriteria)
{
switch (item.Key)
{
case "ID":
iQuery = iQuery.Where(p => p.ID == int.Parse(item.Value));
break;
case "Name":
iQuery = iQuery.Where(p => p.Name.Contains(item.Value));
break;
case "DEP":
iQuery = iQuery.Where(p => p.Department == item.Value);
break;
case "Gender":
iQuery = iQuery.Where(p => p.Gender == item.Value);
break;
case "Role":
iQuery = iQuery.Where(p => p.Role == item.Value);
break;
}
}
在我的真实项目中,我在数据库中有超过1000K的记录。而不是
var iQuery = Members.AsQueryable();
我正在使用
var iQuery = db.Members.AsQueryable();
查询数据需要20到25秒。请帮助我如何在C#LINQ中构建更有效的查询来过滤数据。
答案 0 :(得分:2)
这里的问题不在于LINQ实际在做什么。方案2的查询只会创建类似的内容:
SELECT * FROM
PERSON
WHERE Department = N'Development'
AND Gender = N'Male'
AND Role = N'Manager'
您需要直接针对数据库运行此操作,以确定您的性能瓶颈是什么。您很可能缺少索引,因此强制数据库服务器扫描整个表以获取结果集。
如果您正在使用SQL Server,请尝试运行探查器以确定(假设)LINQ-to-EF正在生成并调整它的确切查询。
答案 1 :(得分:-2)
您需要优化数据库,查看索引
您也可以使用Specification pattern
执行相同的请求 public class NamedPersonSpecification : AbstractSpecification<Person>
{
private string _name;
public NamedPersonSpecification(string name)
{
this._name= name;
}
public override bool IsSatisfiedBy(Person o)
{
return o.Name.Equals(_name);
}
}
并像这样查询:
IQueryable<T>.Where(specification.IsSatisfiedBy)
优点是要更清楚地请求您的LINQ