【发布时间】:2012-06-27 11:19:59
【问题描述】:
我有一个关于使用实体框架进行预测的问题。
我有三张桌子: 简介、传记和传记翻译
我想做以下投影:(传记 = IQueryable)
return biographies.Select(b => new ProfileBiography
{
Id = b.BiographieID,
OwnerId = b.Profile.ProfileID,
Translations =
b.Translations.Select(t => new DocumentTranslation()
{
DocumentId = b.BiographieID,
FileName = t.BiographyTextFile,
Title = t.Title,
Text = t.Text,
LanguageId = t.LanguageID
})
}
我的问题: OwnerId 投影正确,但翻译次数始终为 0。
投影不适用于集合属性吗?
我也试过 biographies.Inlcude("Translations"),但结果是一样的。
更新
我创建了一个小型测试项目,您可以在这里找到:
只有 3 个表(包括创建和插入语句)、一个 EDMX 文件和一个用于加载传记的类。我仍然无法使用它来投影集合导航属性,简单的导航属性可以正常工作。也许有人可以从测试项目中看出我做错了什么......
更新
我尝试了一种新方法,但仍然没有运气:
using (var context = new DatabaseEntities())
{
return context.BiographySets
.Where(bio => bio.ProfileId == profileId)
.Select(bio => new DocumentModel()
{
Id = bio.Id,
OwnerId = bio.Profile.Id,
Translations = context.BiographyTranslationSets.Where(t => t.BiographyId == bio.Id)
.Select(t => new DocumentTranslation()
{
DocumentId = bio.Id,
LanguageId = t.LanguageId,
Text = t.Text
})
}).ToList();
}
更新
如果我使用匿名类型,它会出人意料地工作......
using (var context = new DatabaseEntities())
{
return context.BiographySets
.Where(bio => bio.ProfileId == profileId)
.Select(bio => new
{
Id = bio.Id,
OwnerId = bio.Profile.Id,
Translations = bio.Translations
.Select(t => new
{
DocumentId = bio.Id,
LanguageId = t.LanguageId,
Text = t.Text
})
}).ToList();
}
【问题讨论】:
-
ProfileBiography.Translations 的类型是什么?您可以在 b.Translations.Select(...).ToList() 上执行 ToList()(或其他)吗?
-
是的,投影在集合属性上运行良好。不,您不需要
Include()。我在这里的疯狂猜测是糟糕的映射。查看生成的 SQL 以获取线索。 -
是的,如果我执行以下操作,我可以执行 ToList():biographies.Include("Translations").ToList().Select(.... 它有效。但为什么我需要先调用 ToList()?
-
如果我这样做: biographies.Select(...).ToList() --> 不起作用 biographies.Select(b => new ProfileBiography () { Translations = b.Translations.Select (..).ToList() }) --> 异常:LINQ to Entities 无法识别该方法
-
原因是当您创建
.ToList()时,您正在实现IEnumerable,这是进行此操作所必需的
标签: c# entity-framework projection navigation-properties