当我执行ToList()时,为什么这个LINQ to SQL查询会中断?

Nib*_*Pig 1 c# linq-to-sql

最初我用这样的代码合并了两组结果:

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().

我知道它可能与延迟执行有关,但我没有最模糊的想法.它应该完全一样.

有没有人有什么建议?

The*_*est 6

调用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?不需要施法.不要相信!)