2013-03-18 81 views
3

问题陈述修改LINQ查询

说我有一个查询,其搜索的人的名字:

var result = (from person in container.people select person) 
      .Where(p => p.Name.Contains(some_criterion) 

这将转换到包含像子句的SQL查询:

WHERE NAME LIKE '%some_criterion%' 

这有一些性能影响,因为数据库无法有效地使用名称列上的索引(索引扫描v.s.索引如果我没有弄错)。

为了解决这个问题,我可以决定只StartsWith()来代替,产生使用类似条款就像一个查询:

WHERE NAME LIKE 'some_criterion%' 

使SQL Server使用的索引查找和成本提供性能一些功能。

我希望能够为用户提供一个选择:默认使用StartsWith的行为,但是如果用户想要使用Contains()进行搜索的“增加的灵活性”,那么应该使用这个选项。

有什么我试图

我以为这是小事,并继续实施对字符串的扩展方法。但是,当然,LINQ不接受这个,并抛出异常。

现在,我当然可以去使用if或switch语句并为每个案例创建一个查询,但我更愿意解决这个问题“更高层次”或更一般化。 简而言之:由于实际应用程序的复杂性,使用if语句来区分用例是不可行的。这会导致很多重复和混乱。我真的想以某种方式封装不同的行为(Contains,StartsWith,EndsWith)。

问题

我应该到什么地方或者我应该怎么找?这是与IQueryables组合的情况吗?我很困惑!

+0

Criterium。单数的标准。 – Oxymoron 2013-03-18 14:08:20

+0

这将是“标准”。 – 2013-03-18 14:08:58

+0

啊哈,好的。没有意识到。过度规则适用于我自己的语言英语;) – Oxymoron 2013-03-18 14:10:45

回答

8

而不是过于复杂的事情,如何使用if语句?

var query = from person in container.people 
      select person; 

if (userWantsStartsWith) 
{ 
    query = from p in query 
      where p.Name.Contains(some_criterion) 
      select p; 
} 
else 
{ 
    query = from p in query 
      where p.Name.StartsWith(some_criterion) 
      select p; 
} 

更新

如果你真的需要更复杂的东西尝试寻找LinqKit。它可以让你做到以下几点。

var stringFunction = Lambda.Expression((string s1, string s2) => s1.Contains(s2)); 

if (userWantsStartsWith) 
{ 
    stringFunction = Lambda.Expression((string s1, string s2) => s1.StartsWith(s2)); 
} 

var query = from p in container.people.AsExpandable() 
      where stringFunction.Invoke(p.Name, some_criterion) 
      select p; 

我相信这符合您的

要求我真的希望能够封装不同的行为 (包含,StartsWith,的endsWith)不知何故。

+1

哇,我只是写同样的...是的,我同意 - 保持简单 – 2013-03-18 14:10:39

+0

@Doc:+1更简单 – TalentTuner 2013-03-18 14:12:01

+0

真实的生活查询是相当巨大的,并与其他几个人结合,这就像我的问题所述,不是我正在寻找的解决方案 – Oxymoron 2013-03-18 14:12:57

2

您可以在枚举枚举之前动态更改查询。

var query = container.people.AsQueryable(); 

if (contains) 
{ 
    query = query.Where(p => p.Name.Contains(filter)); 
} 
else 
{ 
    query = query.Where(p => p.Name.StartsWith(filter)); 
} 
0

尝试DIS:

var result = (from person in container.people select person) 
       .Where(p => some_bool_variable ? p.Name.Contains(some_criterium) : p.Name.StartsWith(some_criterium)); 

现实生活中的查询是相当巨大的,与其他几个人联合在一起。这就像我的问题所述,不是我正在寻找的解决方案

Sinse你的查询是巨大的:你不能只是定义处理所有事情的存储过程,并调用特定的查询参数(可能是几个由main调用的存储过程,例如按名称进行em搜索,按age排序的另一个 - 具有不同的排序顺序等等以保持代码清晰)。