Hen*_*nry 22 c# linq asp.net performance sql-server-2008
我知道一种典型的方式是这样的:
IQueryable query = from staff in dataContext.Staffs;
if(name1 != null)
{
query = from staff in query where (staff.name == name1);
}
Run Code Online (Sandbox Code Playgroud)
但是,从我们从其他开发人员手中接过的程序中,我们看到了这样的代码:
IQueryable query = from staff in dataContext.Staffs;
query = from staff in query where (name1 == null || staff.name == name1);
Run Code Online (Sandbox Code Playgroud)
如果这是一个普通的SQL语句,我肯定会说第二个是不好的做法.因为当name1为null时,它会向查询添加无意义的where子句.
但我是LINQ的新手,所以我不确定LINQ是否有所不同?
Muh*_*hid 18
你可以这样写
IQueryable query = from staff in dataContext.Staffs;
query = from staff in query where (name1 != null && staff.name == name1);
Run Code Online (Sandbox Code Playgroud)
这样,如果您的第一个条件评估为false,则不会评估条件的第二部分
更新:
如果你写
IQueryable query = from staff in dataContext.Staffs;
query = from staff in query where (name1 == null || staff.name == name1);
Run Code Online (Sandbox Code Playgroud)
并且name1为null您的条件的第二部分将不会被评估,因为或条件只需要一个条件返回true
请参阅此链接以获取更多详细信息
Car*_*000 11
通常这种事情使用流畅的语法而不是查询语法来编写更平滑.
例如
IQueryable query = dataContext.Staffs;
if(name1 != null)
{
query = query.Where(x => x.name == name1);
}
Run Code Online (Sandbox Code Playgroud)
所以如果name1为null,你就不做任何Where()调用.如果您有多个不同的过滤器,所有这些过滤器可能需要或可能不需要,也许各种不同的排序顺序,我发现这变得更易于管理.
编辑alex:好的,我正在回答有关仅在值不为null时添加where子句的问题.在回答问题的其他部分时,我尝试使用Entity Framework 4来查看LINQ生成的SQL.你通过转换和调用query来做到这一点.结果是该条款如下:ObjectQuery.ToTraceString()WHERE
WHERE @p__linq__0 IS NULL OR [Extent1].[name] = @p__linq__1
Run Code Online (Sandbox Code Playgroud)
所以,是的,它是经典的错误SQL,如果name列上有索引,不要指望它被使用.
编辑#2:使用LINQ to SQL而不是实体框架再次尝试这一点,结果却截然不同.这一次,尝试查询name1为null会导致根本没有任何WHERE条款,正如您所希望的那样; 尝试将其name1作为"a"导致一个简单的WHERE [t0].[name] = @p0并@p0发送为"a".实体框架似乎没有优化.这有点令人担忧.
最好的方法是创建一个扩展方法,该方法将接受条件语句和where表达式。如果条件为true,则它将使用where表达式,否则将不使用它。这可以极大地清理您的代码,而无需if语句。
public static class LinqExtensions
{
public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> whereClause)
{
if (condition)
{
return query.Where(whereClause);
}
return query;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以像这样编写代码:
IQueryable<Staffs> query = dataContext.Staffs.AsQueryable().WhereIf(name1 != null, x => x.Name == name1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56476 次 |
| 最近记录: |