繁体   English   中英

访问链接表时,Linq 查询导致 null 引用异常

[英]Linq query causes null reference exception when accessing linked tables

所以我对测试博客有以下 linq 查询:

var random = new Random();
var random = context.Blog.OrderBy(x => random.Next())
                         .Where(x => x.DisplayStatus == "Approved")
                         .Select(x => new Blog 
                          { 
                              Title = x.Title,
                              Content = x.Content,
                              AuthorId = x.AuthorId,
                              Author = x.Authors.AuthorName //null pointer exception here
                          }).Take(5).ToList() 

问题是,当它遇到“x.Authors.AuthorName”时,它会抛出一个 null 指针异常。 我不知道为什么。 我知道作者在那里,因为当我使用 linq 表达式(来自 context.Blog 中的 x 等)时它工作正常,并且它在 LinqPad 中工作。 但是,我不能使用 linq 表达式,因为我不知道如何在不使用 lambda 表达式的情况下声明“OrderBy(x => random.Next())”。

这是没有随机的版本

var working = (from x in context.Blog
                 //NO known code to select random
                 where x.DisplayStatus == "Approved"
                 select new Blog 
                 {
                    Title = x.Title,
                    Content = x.Content,
                    AuthorId = x.AuthorId,
                    Author = x.Authors.AuthorName //NO null pointer exception
                 }).Take(5).ToList() 

博客是没有数据库关系的 POCO class。 Authors 是一个数据库实体 class , AuthorName 是一个简单的字符串。 知道这里发生了什么吗?

我不允许添加评论,所以我在这里问。 Authors是什么类型? 从名字我猜它可能是某种类型的Collection

如果一个属性可能是null我经常做的是添加一个?

Author = x.Authors?.AuthorName

您可以使用Guid.NewGuid()获得随机排序:

var random = context.Blog.OrderBy(x => Guid.NewGuid())
                     .Where(x => x.DisplayStatus == "Approved")
                     .Select(x => new Blog 
                      { 
                          Title = x.Title,
                          Content = x.Content,
                          AuthorId = x.AuthorId,
                          Author = x.Authors.AuthorName
                      }).Take(5).ToList() 

SqlFunctions.Rand

var random = context.Blog.OrderBy(x => SqlFunctions.Rand())
                     .Where(x => x.DisplayStatus == "Approved")
                     .Select(x => new Blog 
                      { 
                          Title = x.Title,
                          Content = x.Content,
                          AuthorId = x.AuthorId,
                          Author = x.Authors.AuthorName
                      }).Take(5).ToList() 

将您的查询更改为:

var working = (from x in context.Blog
                 where x.DisplayStaus == "Approved"
                 select new Blog 
                 {
                    Title = x.Title,
                    Content = x.Content,
                    AuthorId = x.AuthorId,
                    Author = x.Authors.AuthorName
                 })
                 .AsEnumerable().OrderBy(x => random.Next())
                 .Take(5).ToList();

编辑:

我不是 100% 确定错误是什么,并想等待 OP 检查我的答案是否真的符合我的想法。

我假设实体框架不会将您的查询转换为 SQL 并因此失去自动加载x.Authors的能力,通过移动OrderBy查询的前“半部分”,可以转换为 SQL 而AsEnumerable().OrderBy()将在 memory 中运行。

所以AsEnumerable()将强制在 SQL 中翻译和执行查询,并且以下OrderBy将在 memory 中运行。

编辑2:

关于如何在 SQL 服务器上执行此操作并且不将整个查询加载到 memory,恐怕我无法帮助您,谷歌搜索带来了这个

Linq 到实体,随机顺序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM