最初我用这样的代码合并了两组结果:
var list1 = from a in IDataSourceObject
blahblah
select a;
var list2 = from a in IDataSourceObject2
blahblah
select a;
var joinedlist = from a in list1
join b in list2 on a.id = b.id
into fishcakes
from b in fishcakes.DefaultIfEmpty()
orderby b.ranking
select new { blah=cakes, etc. }
Run Code Online (Sandbox Code Playgroud)
这曾经工作得很好,但后来我想更多地过滤列表1,所以我这样做:
var list1 = from a in IDataSourceObject
blahblah
select a;
// ToList required because im calling a method in my code
var updatedList1 = from a in list1.ToList()
where myMethod(somestuff) == true
select a;
var list2 = from a in IDataSourceObject2
blahblah
select a;
var joinedlist = from a in updatedList1
join b in list2 on a.id = b.id
into fishcakes
from b in fishcakes.DefaultIfEmpty()
orderby b.ranking
select new { blah=cakes, etc. }
Run Code Online (Sandbox Code Playgroud)
但是我得到一个错误,主要是说OrderBy b.ranking为null.在执行ToList之后,它不再合并结果.我已经检查了updatedList1并且我使myMethod总是返回true,所以基本上问题来自于使用ToList().
我知道它可能与延迟执行有关,但我没有最模糊的想法.它应该完全一样.
有没有人有什么建议?
调用fishcakes.DefaultIfEmpty()
可以null
在其中返回集合.
如果调用.ToList()
,则所有当前结果都将复制到本地(.Net)对象,之后的所有命令.ToList()
都将在您的程序中执行.
如果对.Net集合执行查询,则尝试调用null.ranking
- 抛出NullReferenceException
.同时,SQL Server上的执行不会抛出异常,因为在SQL中可以请求子属性null
(它只会返回null
).
要防止示例中出现异常:您可以过滤项目,ranking
等于null
或替换您的项目
orderby b.ranking
Run Code Online (Sandbox Code Playgroud)
这样的事情(我假设ranking
是int)
orderby b != null ? b.ranking : -1
Run Code Online (Sandbox Code Playgroud)
实现价值的情况也是如此.例如(假设,Item
可能有Category
或可能没有):
// this will work, because it's executed on SQL-side
db.Items
.Select(x=>new { CatId = (int?)x.Category.Id, x.Id})
.ToList();
// this will throw NullRefException, because it's executed against collection in .Net environment, not on SQL Server.
db.Items
.ToList()
.Select(x=>new { CatId = (int?)x.Category.Id, x.Id});
Run Code Online (Sandbox Code Playgroud)
PS:如果你使用Resharper,它会在第一个例子中抱怨,int?
不需要施法.不要相信!)
归档时间: |
|
查看次数: |
395 次 |
最近记录: |