我有3个实体:横幅,包和文件。
One Banner有很多包,一个包有很多文件。
我需要获取所有横幅的所有文件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.IEnumerable
1 [System.Int32])' 方法,并且此方法无法转换为商店表达式。 在 System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent,MethodCallExpression call)at ...
有什么可能出错的想法吗?
注意:我禁用了延迟加载。
答案 0 :(得分:1)
var allFileIDs = context.Banners.SelectMany(b =>
b.Packs.SelectMany(p => p.Files.Select(f => f.ID)))
.ToList();
生成的SQL将如下所示:
SELECT [t2].[ID]
FROM [Banners] AS [t0], [Packs] AS [t1], [Files] AS [t2]
WHERE ([t1].[BannerID] = [t0].[ID]) AND ([t2].[PackID] = [t1].[ID])
没有延迟加载,单个查询。
误解了有关获取所有文件ID的问题。如果您需要将每个横幅投影到BannerModel:
context.Banners.Select(b => new BannerModel {
Images = b.Packs.SelectMany(p => p.Files.Select(f => f.ID))
}).ToList();
您看到异常,因为表达式中有ToList()
,无法转换为SQL。将BannerModel.Images
更改为IEnumerable<int>
类型而不是List<int>
,并从select语句中删除ToList()
调用。
如果您不想更改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();