【问题标题】:Materialize all queryable objects物化所有可查询的对象
【发布时间】:2017-03-23 14:08:26
【问题描述】:

有没有办法实现我使用 LINQ 获得的所有可查询对象?

假设我想根据某些条件获取作者列表以及他们的书籍列表(这是一个示例查询,我希望不需要一些实际的类):

var authorData = from a in ctx.Authors
                where a.Age > 30
                select new // anon class
                {
                    Name = a.Name,
                    City = a.Address.City,
                    Books = from b in ctx.Books
                            where b.Price > 10
                            && b.AuthorId == a.Id
                            select new // anon class
                            {
                                Name = b.Name,
                                Price = b.Price,
                            }
                };

现在我想遍历作者authorData 并做一些工作,比如说打印书籍数量。 Books 列表的类型为IQueryable,为每个作者获取这些对象将对数据库产生一个我想避免的新查询。

foreach(var author in authorData.ToList())
{
    Console.WriteLine(author.Books.Count());
}

如何避免对每个作者进行新的 SQL 查询?有没有办法让 Book 匿名类对象与 Author 匿名类同时实现?

编辑: 最终目标是尽可能少地读取 DB,但拥有所有 AuthorBook 对象。在每个 foreach 循环迭代中实现书籍似乎很可怕。

我什至会接受这样的答案,即在单独的集合中获取 Book 对象,例如 Dictionary 或使 Author/Book 连接方便的东西,但不需要多次读取 DB

【问题讨论】:

    标签: c# linq linq-to-entities entity


    【解决方案1】:

    您可以使用 ToList() 方法进行书籍查询和外部查询。

    var authorData = (from a in ctx.Authors
            where a.Age > 30
            select new // anon class
            {
                Name = a.Name,
                City = a.Address.City,
                Books = (from b in ctx.Books
                        where b.Price > 10
                        && b.AuthorId == a.Id
                        select new // anon class
                        {
                            Name = b.Name,
                            Price = b.Price,
                        }).ToList()
            }).ToList();
    foreach(var author in authorData)
       {
         Console.WriteLine(author.Books.Count());
       }
    

    【讨论】:

    • @TadijaBagarić 有什么例外?
    • 我认为异常是由 b.Price 可以为空引起的。您可以通过将其更改为 b.Price 来解决此问题? 0.匿名类型需要相同的顺序和类型。所以 Price 可能是 int,如果 price 为 null,则会导致异常。
    • @RuardvanElburg 我得到了通常的LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[... 异常。让我们假设没有什么可以为空
    【解决方案2】:
    var authorData = (from a in ctx.Authors
                where a.Age > 30
                select new // anon class
                {
                    Name = a.Name,
                    City = a.Address.City,
                    Books = from b in ctx.Books
                            where b.Price > 10
                            && b.AuthorId == a.Id
                            select new // anon class
                            {
                                Name = b.Name,
                                Price = b.Price,
                            }
                }).ToList();
    

    【讨论】:

    • 这是我尝试的第一件事,但它仍然将书籍匿名类保留为 IQueryable。
    猜你喜欢
    • 2021-11-11
    • 2013-04-27
    • 2015-01-10
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多