我如何正确地将EF Core与AutoMapper Projectto和工会使用



我的设置

  • 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 DTOS和实体框架(CORE(,给消息提供了一个例外:

参数检查:输入序列必须具有'test.module.entities.person'类型的项目,但是它具有'test.module.module.dtos.persondetail的类型项目。


没有问题的示例

运行代码时:

 db.People.Where(p => p.FirstName == "Joe").Union(db.People.Where(p => Age > 30)).ToList(); 

我获得了Person实体,没有例外。


执行计划

这是一个工作计划(与联合有关(:

{value(microsoft.entityframeworkcore.query.internal.enternal.enteryqueryable`1 [test.module.entities.person.person](。其中(Entity =>((Entity!= null(和((63ED0EBD-2C02-C02-C02-CC02-CC02-4496-AC8D(-b836cbf13259 == entity.createdby(或(393a6bb0-b437-4664-beb0-6800f509451b == entity entity entity.createdby(((。.person]((}

现在这是相同的计划,但也有自动应用程序的预测:

{value(microsoft.entityframeworkcore.query.internal.enternal.enteryqueryable`1 [test.module.entities.person.person](。其中(Entity =>((Entity!= null(和((63ED0EBD-2C02-C02-C02-CC02-CC02-4496-AC8D(-b836cbf13259 == entity.createdby(或(393a6bb0-b437-4664-beb0-6800f509451b == entity entity entity.createdby(((。。createby,id = dto.id,recordversion = dto.recordversion,displayLabel =((dto.firstname "( dto.lastName(}(}}


注意:

我只是打电话给Tolist,将此问题减少到最小的形式。我知道这似乎在此示例中不需要使用Projectto。在我的实际代码中,我们使用的是ODATA,我们需要最终结果是将DTO作为可查询对象的投影查询。我也知道,这个联盟并不是一个很好的联盟例子,只是为了简化工会问题。

ia还在各自的GitHub项目上开辟了问题:

entityFrameWorkcore :https://github.com/aspnet/entityframeworkcore/issues/issues/11033

automapper :https://github.com/automapper/automapper/sissues/2537

它是一个EF核心错误,已固定在EF Core 2.1中https://github.com/aspnet/entityframeworkcore/issues/11033

很难确切地分辨出没有更多详细信息的问题,但是请确保您的映射正确,例如如果使用映射配置文件

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Person, PersonDetail>();
    }
}

假设您的EF上下文具有一个集合:

public virtual DbSet<Person> People { get; set; }

然后,您应该能够查询上下文和项目以下内容:

var details = _context.People
    .Where(p => p.LastName == 'Smith')
    .OrderBy(p => p.FirstName)
    .ProjectTo<PersonDetail>
    .ToList();

您不需要纳入ef,因为EF不会跟踪不是实体的结果类型,请参阅跟踪和投影的文档

---更新---

尽管EF核心会在内存中对其进行评估:

var firstNameQuery = db.People
    .Where(p => p.FirstName == "Joe")
    .ProjectTo<PersonDetail>(mapperConfig);
var ageQuery = db.People
    .Where(p => p.FirstName == "Joe")
    .ProjectTo<PersonDetail>(mapperConfig);
var results = firstNameQuery.Union(ageQuery).ToList();

最新更新