尝试获取集合中的第一个项时返回NULL
本文关键字:返回 NULL 第一个 获取 集合 | 更新日期: 2023-09-27 18:26:15
我以前使用存储过程进行了大量开发,以完成所有数据修改。
但我现在需要使用LINQ to SQL,而一项基本的任务让我不知所措。
我有一门课叫Book(书名、作者等)。许多书籍被实例化并添加到公共可观察收藏书籍
到目前为止,我可以看到它收藏了有效的书籍。
我有一个函数DeleteOldestBook(),它只是获取Books中的第一本书,然后删除。这就是我遇到麻烦的地方。
我尝试选择
Book BookToDelete = Books.Take(1) as Book;
但它总是返回NULL。
我找到了一个巧妙的解决方法:
var AllBooks = from BookToDelete in Books select BookToDelete;
foreach (Book BookToDelete in AllBooks)
{
// BookToDelete.dostuff takes place ...
break; // only do 1
}
但这太可怕了,我知道我错过了一些简单的东西。
LINQ专家有什么想法吗?如果您需要更多代码,请告诉我。
提前感谢
Take()
返回一个IEnumerable<Book>
。因此,尝试将其强制转换为Book
失败,返回null值。
请改用Books.First()
或Books.FirstOrDefault()
。
Nittickers的澄清:如果Books
直接来自DataContext
,则Take()
实际上可能返回IQuerable<Book>
。
Take
将返回一个包含n个元素的集合。您仍然需要对该集合进行迭代。在您的情况下,集合大小为1。
First
将返回集合中的第一个项目。
额外信贷
如果您的收藏尚未排序,请使用OrderBy
Book bookToDelete = Books.OrderBy(b => b.SomeDate).First();
只需使用FirstOrDefault()
:
var firstBook = Books.FirstOrDefault();
如果集合中没有书籍,则firstBook
将为null
,否则将设置为第一项。
通常您会想要符合某些标准的第一本书,如果是这样,请事先使用适当的Where
子句:
var firstThriller = Books.Where(b => b.Type == "Thriller")
.FirstOrDefault();
我只会使用
Books.First();
代替
Take(1);
Take-Extension方法返回IQueryable<T>
,而您正试图转换为T
(Book
)。这就是为什么你总是空。
是的,您错过了First()
扩展方法:
Book BookToDelete = Books.First();
请注意,Take(int)
返回一个Books序列(IQueryable<T>
),即使该序列在您的案例中只包含一项。由于没有从IQueryable<T>
到T
的转换,as
将返回null。
Take
返回一个包含单个元素的IEnumerable<T>
,您想要的是:
Books.FirstOrDefault();
返回第一个元素(如果Books
为空,则返回null
)。