Sim*_*ine 7 c# sql linq linq-to-sql
使用Linq-to-SQL,我想知道哪个更适合以下三个,
foos.Where(foo => foo.Bar.HasValue && foo.Bar.Value < 42)
foos.Where(foo => foo.Bar.Value < 42)
foos.Where(foo => foo.Bar < 42)
第一个选项生成一个额外的Bar IS NOT NULL
谓词,可能在大多数DBMS中被优化掉了.如果一个查询对象而不是数据库,则null检查将是必需的,但由于可以创建IQueriable<Foo>
可能在对象上失败而在数据库上失败的泛型查询,因此第一个选项始终有效,尽管Linq和SQL代码都是比第二个选项长一点.Michael Liu提供的第三个选项似乎是两个世界中最好的选择,但是在foo.Bar
类型为bool的情况下不会起作用吗?:( foos.Where(foo => foo.Bar)
导致类型错误,因为此处未进行隐式转换).
是否应该努力编写通用查询,如果在最初设计的上下文之外使用它们将不会失败?
第三种选择是使用“提升”<
运算符,如果任一操作数为空,则返回 false。这使您可以省略对 null 的显式检查,并且适用于所有 LINQ 提供程序:
foos.Where(foo => foo.Bar < 42)
Run Code Online (Sandbox Code Playgroud)
如果 的编译时类型为foos
,IEnumerable<Foo>
则foo.Bar < 42
相当于
foo.Bar.GetValueOrDefault() < 42 && foo.Bar.HasValue
Run Code Online (Sandbox Code Playgroud)
只不过foo.Bar
只访问一次。(我通过在 Reflector 中反编译程序得到了这一点。有趣的是,编译器选择在检查 null之前执行比较,但作为微优化,这是有意义的。)
如果 的编译时类型为foos
,IQueryable<Foo>
则foo.Bar < 42
相当于
foo.Bar < (int?)42
Run Code Online (Sandbox Code Playgroud)
是否以及如何检查空值取决于 LINQ 提供程序。
更新:如果 的类型foo.Bar
是bool?
并且您只想包含为foo.Bar
true 的记录(即既不是 false 也不是 null),那么您可以编写
foos.Where(foo => foo.Bar == true)
Run Code Online (Sandbox Code Playgroud)
或者
foos.Where(foo => foo.Bar.GetValueOrDefault())
Run Code Online (Sandbox Code Playgroud)