尝试获取集合中的第一个项时返回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专家有什么想法吗?如果您需要更多代码,请告诉我。

提前感谢

尝试获取集合中的第一个项时返回NULL

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>,而您正试图转换为TBook)。这就是为什么你总是空。

是的,您错过了First()扩展方法:

Book BookToDelete = Books.First();

请注意,Take(int)返回一个Books序列(IQueryable<T>),即使该序列在您的案例中只包含一项。由于没有从IQueryable<T>T的转换,as将返回null。

Take返回一个包含单个元素的IEnumerable<T>,您想要的是:

Books.FirstOrDefault();

返回第一个元素(如果Books为空,则返回null)。