EntityFramework-将ID加载到较低级别,而不加载其他列
本文关键字:加载 其他 较低级 ID EntityFramework- | 更新日期: 2023-09-27 18:01:50
我有三个实体:横幅、包和文件。
一个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选择上遇到了一个错误:
系统。NotSupportedException:LINQ to Entities不识别方法"系统"。集合。通用的列出
1[System.Int32] ToList[Int32](System.Collections.Generic.IEnumerable
1[System.Int32]('方法,而此方法无法转换为存储表达式。在系统数据对象。ELinq。ExpressionConverter。MethodCallTranslator。默认转换器。翻译(ExpressionConverterparent,MethodCallExpression调用(。。。
你知道可能出了什么问题吗?
注意:我禁用了懒惰加载。
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();