我以前使用Stored Procs进行了大量的开发来进行所有数据修改。
但我现在需要使用LINQ To SQL,而基本的基本任务让我难以理解。
我有一个名为Book(Title,Author等)的课程。实例化并添加了许多书籍 public ObservableCollection Books
到目前为止,我可以看到它的藏品中有有效的书籍。
我有一个函数 DeleteOldestBook(),它只是获取书籍中的第一本书,并删除。这是我遇到麻烦的地方。
我尝试选择
Book BookToDelete = Books.Take(1) as Book;
但它总是返回NULL。
我做了一个hacky解决方法:
var AllBooks = from BookToDelete in Books select BookToDelete;
foreach (Book BookToDelete in AllBooks)
{
// BookToDelete.dostuff takes place ...
break; // only do 1
}
但这太糟糕了,我知道我错过了一些简单的东西。
LINQ专家的任何想法?如果您需要更多代码,请告诉我。
提前致谢
答案 0 :(得分:10)
Take()
会返回IEnumerable<Book>
。因此,您将其转换为Book
的尝试失败,返回空值。
改为使用Books.First()
或Books.FirstOrDefault()
。
对Nitpickers的澄清:如果Take()
直接来自IQuerable<Book>
,则Books
实际上可能会返回DataContext
。
答案 1 :(得分:6)
Take
将返回一个包含n个元素的集合。您仍然需要迭代该集合。在您的情况下,集合大小为1。
First
将返回集合中的第一项。
额外信用
如果您的收藏品尚未排序,请使用OrderBy
Book bookToDelete = Books.OrderBy(b => b.SomeDate).First();
答案 2 :(得分:6)
只需使用FirstOrDefault()
:
var firstBook = Books.FirstOrDefault();
如果集合中没有图书,firstBook
将为null
,否则将设置为第一项。
通常情况下你会希望通过一些标准获得第一本书,如果是这样的话,请事先使用适当的Where
子句:
var firstThriller = Books.Where(b => b.Type == "Thriller")
.FirstOrDefault();
答案 3 :(得分:3)
我会用
Books.First();
而不是
Take(1);
Take Extension方法会返回IQueryable<T>
,您尝试转换为T
(Book
)。这就是你总是得到null的原因。
答案 4 :(得分:2)
是的,您错过了First()
扩展程序:
Book BookToDelete = Books.First();
请注意,Take(int)
会返回一系列图书(IQueryable<T>
) - 即使该序列仅包含您的案例中的一个项目。由于没有IQueryable<T>
到T
的转换,as
将返回null。
答案 5 :(得分:1)
Take
会返回包含单个元素的IEnumerable<T>
,您想要的是:
Books.FirstOrDefault();
返回第一个元素(如果null
为空,则返回Books
。)