有人可以向我解释这个LINQ / Entity Framework查询实际上是如何工作的吗?

时间:2016-11-16 18:13:20

标签: c# entity-framework linq

我对Entity Framework很陌生,今天我一直在寻找一种方法来处理我所包含的导航属性的条件。基本上我的所有实体都被标记为'在数据库中删除而不是实际删除,所以我希望我的WebAPI返回所有的父母'没有标记为已删除的对象,但也只包括尚未删除的嵌套导航属性。

我一直在寻找的解决方案,这确实有效(在暂时禁用我的上下文的延迟加载之后):

var projectQuery = await db.Projects.Where(x => !x.IsDeleted).Select(x => new
            {
                Project = x,
                Id = x.Id,
                Name = x.Name,
                Description = x.Description,
                Owner = x.Owner,
                Sponsor = x.Sponsor,
                DateCreated = x.DateCreated,
                DateOpened = x.DateOpened,
                DateClosed = x.DateClosed,
                IsDeleted = x.IsDeleted,
                CreatedBy = x.CreatedBy,
                Expenses = x.Expenses.Where(y => !y.IsDeleted),
                TimeEntries = x.TimeEntries.Where(y => !y.IsDeleted)
            }).ToListAsync();

            results = projectQuery.Select(x => Mapper.Map<ProjectDto>(x.Project)).ToList();

显然,我可以遵循发生了什么的一般概念,即将结果抛到匿名对象中,以便我能够在子集合(Expenses和TimeEntries)上指定Where条件。我的困惑来自于我需要将对象恢复到原始类型......原始对象本身作为我创建的每个匿名对象的属性包含在内,然后用作&#39; final&# 39;我可以将地图映射回我的DTO或我需要的其他任何东西。

这是什么黑魔法?这个对象引用看起来如何知道如何使用我在匿名对象中定义的属性作为自己的属性?我真的希望Project属性与我从DbContext获得的项目完全相同,并且震惊地发现它确实起作用。我发现这是从几个来源解决我的问题,其中没有一个实际上提供了一些关于这里发生了什么的见解

1 个答案:

答案 0 :(得分:2)

EF正在使用Expression Trees来解析您的查询。通过传入原始实体,它可以看到在新对象图上分配的内容,然后使用该信息构建等效的数据库查询。执行查询时,它也会投影到您定义的对象结构中。

映射和投影是为什么在EF查询中只能运行一组有限的.Net函数