如何动态地构造/更改LINQ语句的一部分

时间:2014-11-05 22:30:51

标签: c# linq

我的应用中有一个方法,需要根据一组条件读取,过滤和提供数据。 我试图用LINQ来实现这个目标:

var pipelineData = from data in new XPQuery<AccountView3.PipelineData>(uow)
         where data.Stage.ToLower().Contains("won")
         && data.RevenueStartDate.Value.Year == DateTime.Today.Year
         && data.WeekOfTheYear >= priorWeekCutoff
         && (!string.IsNullOrEmpty(data.PlatformTcv) && data.PlatformTcv != "#N/A")
         select data; 

本身,这很好用。问题是 - 取决于正在传递的搜索条件,而不是data.PlatformTvc,它可能是data.WorkspaceTvc,或data.Cyber​​Tvc等... 我没有办法提前知道哪些可能的5种选择需要评估。

我的问题是:有没有办法以这种方式构造LINQ语句,语句的一部分是有条件地执行的。因此,如果用户通过&#34;平台&#34;作为搜索条件,LINQ语句将读取... string.IsNullOrEmpty(data.PlatformTcv),但如果条件为&#34; Cyber​​&#34;,则此LINQ语句应为... string.IsNullOrEmpty(data.CyberTcv) 有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:9)

不确定。利用LINQs延迟执行模型并在查询中嵌入可更改的谓词。例如:

Func<DataObject, string> accessor = data => data.PlatformTcv;

var pipelineData = from data in new XPQuery<AccountView3.PipelineData>(uow)
                   where data.Stage.ToLower().Contains("won")
                       && data.RevenueStartDate.Value.Year == DateTime.Today.Year
                       && data.WeekOfTheYear >= priorWeekCutoff
                       && (!string.IsNullOrEmpty(accessor(data))
                       && accessor(data) != "#N/A")
                   select data;

var basedOnPlatform = pipelineData.ToArray();

accessor = data => data.CyberTV;

var basedOnCyber = pipelineData.ToArray();

(这假设查询元素类型为DataObject。当然,您可以将其替换为您正在使用的任何类型的实际名称。

请记住,这将使LINQ更难理解,并始终牢记查询的延迟执行性质。即如果他们没有实现&#34;与其他一些集合(例如调用ToArray())一样,下次执行时会显示对基础查询的更改。

答案 1 :(得分:2)

您可以为所有查询的相同部分创建IQueryable:

var pipelineData = from data in new XPQuery<AccountView3.PipelineData>(uow)
     where data.Stage.ToLower().Contains("won");
     // etc

然后应用特定过滤器:

if (somecondition) 
{
    pipelineData = pipelineData.Where(x => x.SomeField == "somevalue");
}
// etc