0

我有 3 个实体:横幅、包和文件。

一个横幅有很多包,一个包有很多文件。

我需要获取所有横幅的所有文件 ID。我尝试了以下方法:

  IList<BannerModel> banners = context.Banners
    .OrderBy(x => Guid.NewGuid())
    .Take(count)       
    .Select(x => 
      new BannerModel {
        Images = x.Packs.SelectMany(p => p.Files.Select(f => f.Id)).ToList()
      }).ToList();

但是,我在选择文件 ID 时遇到错误:

System.NotSupportedException:LINQ to Entities 无法识别方法 'System.Collections.Generic.List 1[System.Int32] ToList[Int32](System.Collections.Generic.IEnumerable1[System.Int32])' 方法,并且此方法无法转换为存储表达式。在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) 在 ...

知道可能出了什么问题吗?

注意:我禁用了延迟加载。

4

1 回答 1

1
var allFileIDs = context.Banners.SelectMany(b => 
                           b.Packs.SelectMany(p => p.Files.Select(f => f.ID)))
                        .ToList();

Resulting SQL will look like:

SELECT [t2].[ID]
FROM [Banners] AS [t0], [Packs] AS [t1], [Files] AS [t2]
WHERE ([t1].[BannerID] = [t0].[ID]) AND ([t2].[PackID] = [t1].[ID])

No lazy-loading, single query.


Misunderstood your question about getting all file ids. If you need to project each banner to BannerModel:

context.Banners.Select(b => new BannerModel {
          Images = b.Packs.SelectMany(p => p.Files.Select(f => f.ID))
        }).ToList();

You see exception, because you have ToList() in expression, which cannot be converted into SQL. Change BannerModel.Images to be of type IEnumerable<int> instead of List<int>, and remove ToList() call from select statement.


One more option if you don't want to change type of BannerModel.Images:

context.Banners.Select(b => b.Packs.SelectMany(p => p.Files.Select(f => f.ID)))
               .ToList() // brings next projection into memory
               .Select(ids => new BannerModel { Images = ids.ToList() })
               .ToList();
于 2013-02-28T21:38:11.573 回答