简体   繁体   English

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

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

So I have the following linq query for a test blog:所以我对测试博客有以下 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() 

The trouble is, it throws a null pointer exception when it hits 'x.Authors.AuthorName'.问题是,当它遇到“x.Authors.AuthorName”时,它会抛出一个 null 指针异常。 I cannot figure out why.我不知道为什么。 I know the author is there because it works fine when I use linq expressions (from x in context.Blog...etc), and it works in LinqPad.我知道作者在那里,因为当我使用 linq 表达式(来自 context.Blog 中的 x 等)时它工作正常,并且它在 LinqPad 中工作。 I can't use the linq expression, though, because I don't know how to declare 'OrderBy(x => random.Next())' without using a lambda expression.但是,我不能使用 linq 表达式,因为我不知道如何在不使用 lambda 表达式的情况下声明“OrderBy(x => random.Next())”。

this is the version that works without the random这是没有随机的版本

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

Blog is a POCO class with no database relations.博客是没有数据库关系的 POCO class。 Authors is a database entity class with AuthorName being a simple string. Authors 是一个数据库实体 class , AuthorName 是一个简单的字符串。 Any idea on what is going on here?知道这里发生了什么吗?

I am not allowed to add a comment, so I ask here.我不允许添加评论,所以我在这里问。 What type is Authors ? Authors是什么类型? From the name I guess it could be some type of Collection .从名字我猜它可能是某种类型的Collection

What I often do if one Property might be null is to add a ?如果一个属性可能是null我经常做的是添加一个? :

Author = x.Authors?.AuthorName

You can get random sort using Guid.NewGuid() :您可以使用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() 

Or SqlFunctions.Rand :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() 

Change your query to this:将您的查询更改为:

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

Edit:编辑:

I wasn't 100% sure what the error is and wanted to wait for the OP to check if my answer actually does what I believe it does.我不是 100% 确定错误是什么,并想等待 OP 检查我的答案是否真的符合我的想法。

I assumed that Entity Framework will not translate your query to SQL and therefor lose the ability to automatically load x.Authors , by moving the OrderBy the first "half" of the query, can be translated to SQL while the AsEnumerable().OrderBy() will run in memory.我假设实体框架不会将您的查询转换为 SQL 并因此失去自动加载x.Authors的能力,通过移动OrderBy查询的前“半部分”,可以转换为 SQL 而AsEnumerable().OrderBy()将在 memory 中运行。

So AsEnumerable() will force the query to be translated and exceuted in SQL, and the following OrderBy will run in memory.所以AsEnumerable()将强制在 SQL 中翻译和执行查询,并且以下OrderBy将在 memory 中运行。

Edit2:编辑2:

About how to do it on the SQL Server and not loading the whole query to memory, I am afraid I can't help you with that, a google search brought this关于如何在 SQL 服务器上执行此操作并且不将整个查询加载到 memory,恐怕我无法帮助您,谷歌搜索带来了这个

Linq to Entities, random order Linq 到实体,随机顺序

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

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