Rya*_*ndy 2 .net c# linq linq-to-sql
我有很多丑陋的代码,看起来像这样:
if (!string.IsNullOrEmpty(ddlFileName.SelectedItem.Text))
results = results.Where(x => x.FileName.Contains(ddlFileName.SelectedValue));
if (chkFileName.Checked)
results = results.Where(x => x.FileName == null);
if (!string.IsNullOrEmpty(ddlIPAddress.SelectedItem.Text))
results = results.Where(x => x.IpAddress.Contains(ddlIPAddress.SelectedValue));
if (chkIPAddress.Checked)
results = results.Where(x => x.IpAddress == null);
...etc.
Run Code Online (Sandbox Code Playgroud)
results是一个IQueryable<MyObject>.
我们的想法是,对于这些无数下拉列表和复选框中的每一个,如果下拉列表中选择了某些内容,则用户希望匹配该项目.如果选中该复选框,则用户特别需要该字段为空或空字符串的那些记录.(UI不允许同时选择它们.)这一切都添加到LINQ表达式,在我们添加了所有条件之后,它将在最后执行.
它看起来像,就必须有某种方式拉出一个Expression<Func<MyObject, bool>>或两个,这样我可以把重复部分的方法,只是在传递什么样的变化.我在其他地方做过这个,但这套代码让我受阻.(另外,我想避免使用"动态LINQ",因为我希望尽可能保持类型安全.)任何想法?
我将它转换为单个Linq语句:
var results =
//get your inital results
from x in GetInitialResults()
//either we don't need to check, or the check passes
where string.IsNullOrEmpty(ddlFileName.SelectedItem.Text) ||
x.FileName.Contains(ddlFileName.SelectedValue)
where !chkFileName.Checked ||
string.IsNullOrEmpty(x.FileName)
where string.IsNullOrEmpty(ddlIPAddress.SelectedItem.Text) ||
x.FileName.Contains(ddlIPAddress.SelectedValue)
where !chkIPAddress.Checked ||
string.IsNullOrEmpty(x. IpAddress)
select x;
Run Code Online (Sandbox Code Playgroud)
它并不短,但我发现这个逻辑更清晰.
在这种情况下:
//list of predicate functions to check
var conditions = new List<Predicate<MyClass>>
{
x => string.IsNullOrEmpty(ddlFileName.SelectedItem.Text) ||
x.FileName.Contains(ddlFileName.SelectedValue),
x => !chkFileName.Checked ||
string.IsNullOrEmpty(x.FileName),
x => string.IsNullOrEmpty(ddlIPAddress.SelectedItem.Text) ||
x.IpAddress.Contains(ddlIPAddress.SelectedValue),
x => !chkIPAddress.Checked ||
string.IsNullOrEmpty(x.IpAddress)
}
//now get results
var results =
from x in GetInitialResults()
//all the condition functions need checking against x
where conditions.All( cond => cond(x) )
select x;
Run Code Online (Sandbox Code Playgroud)
我只是显式声明了谓词列表,但是可以生成这些,例如:
ListBoxControl lbc;
CheckBoxControl cbc;
foreach( Control c in this.Controls)
if( (lbc = c as ListBoxControl ) != null )
conditions.Add( ... );
else if ( (cbc = c as CheckBoxControl ) != null )
conditions.Add( ... );
Run Code Online (Sandbox Code Playgroud)
你需要一些方法来检查你需要检查的MyClass的属性,为此你必须使用反射.