C# 如何使用LINQ对发送到DataGridView的行重构过滤器
**有没有一种更简单的方法可以用这种方式过滤DataGridView中的行? 因为它看起来有点复杂 **C# 如何使用LINQ对发送到DataGridView的行重构过滤器,c#,linq,datagridview,C#,Linq,Datagridview,**有没有一种更简单的方法可以用这种方式过滤DataGridView中的行? 因为它看起来有点复杂 ** 要求改进工作代码的问题更容易解决,因为它们暗示了一定程度的意见。我相信您的代码中需要一些设计改进,而可选Linq谓词的当前形式将导致Sql查询,当Persons表中有大量行时,这些查询的性能会很差 将解析查询的用户输入过滤器与实际查询数据的行为分开。通常,这将被划分为不同的类,甚至不同的程序集,代表这些不同的层/关注点,例如表示层和数据/存储库层 在访问数据库之前引入验证。没有筛选器的查询将
要求改进工作代码的问题更容易解决,因为它们暗示了一定程度的意见。我相信您的代码中需要一些设计改进,而可选Linq谓词的当前形式将导致Sql查询,当Persons表中有大量行时,这些查询的性能会很差 将解析查询的用户输入过滤器与实际查询数据的行为分开。通常,这将被划分为不同的类,甚至不同的程序集,代表这些不同的层/关注点,例如表示层和数据/存储库层 在访问数据库之前引入验证。没有筛选器的查询将尝试检索所有人员行,浪费IO,并可能导致应用程序因OutOfMemoryException而崩溃。此外,您还可以将验证分离到单独的方法或类中。 根据我的评论,“可选”谓词过滤器模式会导致Sql的@filter null和column=@filter或@filter为null,这将导致Sql查询性能差,并将缓存不适合其他过滤器排列的计划。这里要做的是完全忽略任何不需要的谓词,即用户将筛选器留空的谓词。我在下面使用了IQueryable的一个简单组合来实现这一点,但对于更高级的情况,您需要使用PredicateBuilder或DynamicClinQ来实现更复杂的谓词。
这看起来像是在LINQ结果集上进行过滤,而不是在DataGridView上进行任何过滤。您想问什么?问题@Ahmed为什么不创建一个查询或存储过程来获取您正在查找的返回数据并将其绑定到DataGridView,然后从那里您仍然可以使用DataSet.DataTable.filter methodSimplicity对数据进行筛选和重新绑定,灵活的UI有大量的过滤器排列,以column=@filter或column IS NULL的形式生成谓词将在Sql中创建糟糕的查询计划。我建议构建或使用,以便只应用适用的谓词;或者像这样冷创建BindingSource实例也可以工作BindingSource bs=BindingSourcedataGridView1.DataSource;b.Filter=你的过滤器或类似表达式my brother@Habib此方法帮助我使用文本框、2个Comboxes和3个DateTimePickerd累积过滤对DGV进行多重过滤我寻找另一种简单的方法来完成此操作Thanx my brother@StuartLC,很抱歉我的英语不好我会尝试此方法过滤效果不好,我会把考试成绩给你的
private void Reread()
{
string nameFilter = txtSearch.Text;
string addressFilter = comboBox1.SelectedIndex > 0 ? comboBox1.Text : "";
string depFilter = comboBox2.SelectedIndex > 0 ? comboBox2.Text : "";
DateTime? birthdate = chkBirthdate.Checked ? dateTimePicker1.Value.Date : (DateTime?) null;
DateTime? fromDate = chkRange.Checked ? dateTimePicker2.Value.Date : (DateTime?)null;
DateTime? toDate = chkRange.Checked ? dateTimePicker3.Value.Date : (DateTime?)null;
using (DbDataContext db = new DbDataContext())
{
var result = from p in db.Persons
where
(nameFilter.Length > 0 && p.FullName.Contains(nameFilter) || nameFilter.Length == 0)
&& (addressFilter.Length > 0 && p.Address == addressFilter || addressFilter.Length == 0)
&& (depFilter.Length > 0 && p.Department == depFilter || depFilter.Length == 0)
&& (birthdate == null || (birthdate != null && p.Birthdate == birthdate))
&& ((fromDate == null || toDate == null) || (fromDate != null && toDate != null && p.Birthdate >= fromDate && p.Birthdate <= toDate))
select p;
var resultData = result.ToList();
dataGridView1.DataSource = resultData;
}
IList<Person> FindPersons(string nameFilter, string addressFilter,
DateTime? birthdate, .. etc)
{
using (var db = new DbDataContext())
{
var query = db.Persons.AsQueryable();
if (!string.IsNullOrWhitespace(nameFilter))
{
query = query.Where(p => p.FullName.Contains(nameFilter));
}
if (!string.IsNullOrWhitespace(addressFilter))
{
query = query.Where(p => p.Address == addressFilter);
}
if (!string.IsNullOrWhitespace(depFilter))
{
query = query.Where(p => p.Department == depFilter);
}
if (birthdate.HasValue)
{
query = query.Where(p => p.Birthdate == birthdate);
}
query = query.Take(1000); // Sanity, limit the rows
return query.ToList();
}
}
protected void OnSearchPersonClick()
{
// Parsing
var nameFilter = txtSearch.Text;
var addressFilter = comboBox1.SelectedIndex > 0 ? comboBox1.Text : "";
DateTime? birthdate = chkBirthdate.Checked
? dateTimePicker1.Value.Date
: (DateTime?) null;
// etc
// Validation
if (string.IsNullOrWhitespace(nameFilter)
&& string.IsNullOrWhitespace(addressFilter)
&& !(birthdate.HasValue)) // etc
{
ShowErrorMessageToUser("Please provide at least one filter");
return;
}
// Bind
dataGridView1.DataSource = FindPersons();
}