我的设置
- ASP.NET Core 2.0
- EntityFrameworkCore 2.0.1
- AutoMapper 6.2.2
问题
我有一个带有DTO(数据传输对象)PersonDetail
和实体Person
的项目。当我调用
db.People.Where(p => p.FirstName == "Joe").Union(db.People.Where(p => Age > 30)).ProjectTo<PersonDetail>(mapperConfig).ToList();
我不理解PersonDetail
数据传输对象(DTO),并且Entity Framework(Core)抛出异常信息:
ArgumentException: 输入序列必须具有类型为“Test.Module.Entities.Person”的项目,但它具有类型为“Test.Module.Dtos.PersonDetail”的项目。
没有问题的示例
当我运行以下代码时:
db.People.Where(p => p.FirstName == "Joe").Union(db.People.Where(p => Age > 30)).ToList();
我无条件获取Person
实体。
执行计划
这是一个带有联合的工作计划:
{value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Test.Module.Entities.Person]).Where(entity => ((entity != null) And ((63ed0ebd-2c02-4496-ac8d-b836cbf13259 == entity.CreatedBy) Or (393a6bb0-b437-4664-beb0-6800f509451b == entity.CreatedBy)))).Union(value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Test.Module.Entities.Person]))}
现在是同样的计划,但也包括了Automapper projections:
{value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Test.Module.Entities.Person]).Where(entity => ((entity != null) And ((63ed0ebd-2c02-4496-ac8d-b836cbf13259 == entity.CreatedBy) Or (393a6bb0-b437-4664-beb0-6800f509451b == entity.CreatedBy)))).Union(value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Test.Module.Entities.Person])).Select(dto => new PersonDetail() {FirstName = dto.FirstName, LastName = dto.LastName, Deleted = dto.Deleted, Age = dto.Age, CreatedUtc = dto.CreatedUtc, CreatedBy = dto.CreatedBy, Id = dto.Id, RecordVersion = dto.RecordVersion, DisplayLabel = ((dto.FirstName + " ") + dto.LastName)})}
注意:
我只调用ToList以将此问题简化到最小形式。我知道在这个示例中似乎不需要使用ProjectTo。在我的实际代码中,我们正在使用OData,我们需要将最终结果作为DTO的Queryable对象进行投影查询。我也知道这个Union不是一个好的Union示例,但是为了简化Union问题而已。
我还在相应的GitHub项目上提出了问题:
EntityFrameworkCore:https://github.com/aspnet/EntityFrameworkCore/issues/11033
AutoMapper:https://github.com/AutoMapper/AutoMapper/issues/2537