合并从不同表中投影到一个实体的两个 iqueryable
本文关键字:实体 一个 iqueryable 两个 投影 合并 | 更新日期: 2023-09-27 17:56:23
我已经尝试过这个答案,这个和这个来合并两个可查询对象。但我总是收到以下错误:
类型"Estudio"出现在单个 LINQ to 实体查询中的两个结构不兼容的初始化中。可以在同一查询中的两个位置初始化类型,但前提是在两个位置设置了相同的属性,并且这些属性的设置顺序相同。
我使用以下代码从两个不同但相似的实体框架实体(EXAMEN 和 EXPLORACION)映射到我的域实体 Estudio。
IQueryable<Estudio> listExamen = context.Set<EXAMEN>().Project().To<Estudio>();
IQueryable<Estudio> listExploracion = context.Set<EXPLORACION>().Project().To<Estudio>();
var listCombined = listExamen.Concat(listExploracion);
无论如何,通过合并两个列表来生成一个 IQueryable(不可枚举)吗?如果使用 AsEnumerable(),则会在内存上执行以下筛选器(Order、Take 等)。所以我需要合并列表,但仍然可以在不执行查询的情况下将过滤器应用于合并的列表。
//This will force the next condition is executed on memory
var listCombined = listExamen.AsEnumerable().Concat(listExploracion);
这可能吗?
我会尝试在 linq 查询中选择匿名类型中的数据,执行联合并添加条件。
var listExamen = context.Examen
.Select(x => new { x.Prop1, x.Prop2, ... }); // Add properties
var listExploracion = context.Exploraction
.Select(x => new { x.Prop1, x.Prop2, ... }); // Add identical properties
var listCombined = listExamen.Concat(listExploracion);
var whereAdded = listCombines
.Where(x => x.Prop1 == someValue);
var result = whereAdded
.Skip(skipCount)
.Take(takeCount)
.ToList();
注意:我不知道您是否可以将公用表表达式(跳过/获取的SQL必要性)与联合查询结合使用
注意:我已经更改了用于创建表达式的方法,因为我不知道您的方法(Project
,To
)
所以我认为解决方案不是强制转换为特定类型,而是转换为匿名类型,因为它可能可以转换为 SQL。
警告:未进行测试
我的解决方案是修改我的映射代码。我必须一次投影整个实体,而不是使用单个基于属性的映射器,确保所有属性都以相同的顺序给出。
因此,而不是ForMember
语法:
Mapper.CreateMap<Client, PersonResult>()
.ForMember(p => p.Name, cfg => cfg.MapFrom(c => c.Person.FirstName + " " + c.Person.LastName))
...
我使用了ProjectUsing
语法:
Mapper.CreateMap<Client, PersonResult>()
.ProjectUsing(c => new PersonResult()
{
Name = c.Person.FirstName + " " + c.Person.LastName
...
});
这一定是因为自动映射器构建其投影的方式。
解决此问题的一种方法是添加虚拟类型:
class Estudio<T> : Estudio { }
和新的映射:
Mapper.CreateMap<Estudio , Estudio>();
Mapper.CreateMap<EXAMEN , Estudio<EXAMEN>>();
Mapper.CreateMap<EXPLORACION, Estudio<EXPLORACION>>();
需要注意的是,Estudio
中的所有字段都需要一些映射值。不能使用忽略。返回0
或""
是可以的。现在我们可以做:
var a = context.Set<EXAMEN>().ProjectTo<Estudio<EXAMEN>>();
var b = context.Set<EXPLORACION>().ProjectTo<Estudio<EXPLORACION>>();
return a.ProjectTo<Estudio>().Concat(b.ProjectTo<Estudio>());