【问题标题】:Projections with Entity Framework使用实体框架进行投影
【发布时间】: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"),但结果是一样的。

更新

我创建了一个小型测试项目,您可以在这里找到:

TestProject.zip

只有 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


【解决方案1】:

好的,我发现了问题:

这是我的 DocumentModel 课程:

public class DocumentModel
{
    public DocumentModel()
    {
        _translations = new List<DocumentTranslation>();
    }

    public int Id { get; set; }

    public int OwnerId { get; set; }

    private List<DocumentTranslation> _translations;
    public IEnumerable<DocumentTranslation> Translations
    {
        get { return _translations; }
        set { _translations = value.ToList(); }
    }
}

这就是问题所在:

set { _translations = value.ToList(); }

我无法在我的 Setter 中调用 ToList(),因为它会破坏查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多