簡體   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