Automapper 投影和联合
Automapper projection and union
联合和自动映射器投影有问题。
我有两个实体:
public class Entity
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
}
public class ExtendedEntity
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
public int SomeOtherProp { get; set; }
}
和投影:
public class EntityProjection
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
public int SomeOtherProp { get; set; }
public string Source { get; set; }
}
我将实体映射到一个投影,实体没有 SomeOtherProp 所以我将其设置为 0:
public class EntityProfile : Profile
{
protected override void Configure()
{
CreateMap<ExtendedEntity, EntityProjection>()
.ForMember(dest => dest.Source, opt => opt.MapFrom(src => "ext entity"));
CreateMap<Entity, EntityProjection>()
.ForMember(dest => dest.SomeOtherProp, opt => opt.MapFrom(src => 0))
.ForMember(dest => dest.Source, opt => opt.MapFrom(src => "entity"));
}
}
当我尝试使用下一个代码时出现错误:
var entities = context.Set<Entity>()
.Project().To<EntityProjection>();
var extEntities = context.Set<ExtendedEntity>()
.Project().To<EntityProjection>();
var result = entities.Union(extEntities).OrderBy(p => p.ActionDate).ToList();
错误文本:类型 'UserQuery+EntityProjection' 出现在单个 LINQ to Entities 查询中的两个结构不兼容的初始化中。类型可以是...
这意味着投影中的属性必须以相同的顺序初始化,我如何通过自动映射器设置投影属性初始化顺序?
很晚的回答,简短的版本似乎是 "You can't"。
我有完全相同的问题 (Can I force Automapper to initialise properties in a certain order?),最终在 LINQ select 语句中映射了所有内容。
为方便起见,我在我的 DTO 中将其设为静态方法(缩减代码):
public static IQueryable<MyDto> QueryableFromTaskType1(
IQueryable<TaskType1> query)
{
return query.Select(src => new MyDto()
{
TaskId = src.Id,
AssetTypeName = src.Asset.AssetType.Name,
AssetId = src.Asset.Id,
AssetCode = src.Asset.Code,
AssetName = src.Asset.Name,
});
}
public static IQueryable<MyDto> QueryableFromTaskType2(
IQueryable<TaskType2> query)
{
return query.Select(src => new MyDto()
{
TaskId = src.Id,
AssetTypeName = src.AssetTypeName,
AssetId = src.AssetId,
AssetCode = src.AssetCode,
AssetName = src.AssetName,
});
}
然后你可以得到你的对象,作为一个 IQueryable,简单地通过适当的静态方法传递它们(它将 select 附加到 DTO - 或其他已知的项目中)然后 Union 或 Concat结果 IQueryables。
唯一的缺点是 Automapper 通常会处理递归自动映射,尽管我很确定无论如何都不会很好地映射到 SQL,所以您可能不会损失太多。
联合和自动映射器投影有问题。
我有两个实体:
public class Entity
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
}
public class ExtendedEntity
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
public int SomeOtherProp { get; set; }
}
和投影:
public class EntityProjection
{
public DateTime ActionDate { get; set; }
public int SomeProp { get; set; }
public int SomeOtherProp { get; set; }
public string Source { get; set; }
}
我将实体映射到一个投影,实体没有 SomeOtherProp 所以我将其设置为 0:
public class EntityProfile : Profile
{
protected override void Configure()
{
CreateMap<ExtendedEntity, EntityProjection>()
.ForMember(dest => dest.Source, opt => opt.MapFrom(src => "ext entity"));
CreateMap<Entity, EntityProjection>()
.ForMember(dest => dest.SomeOtherProp, opt => opt.MapFrom(src => 0))
.ForMember(dest => dest.Source, opt => opt.MapFrom(src => "entity"));
}
}
当我尝试使用下一个代码时出现错误:
var entities = context.Set<Entity>()
.Project().To<EntityProjection>();
var extEntities = context.Set<ExtendedEntity>()
.Project().To<EntityProjection>();
var result = entities.Union(extEntities).OrderBy(p => p.ActionDate).ToList();
错误文本:类型 'UserQuery+EntityProjection' 出现在单个 LINQ to Entities 查询中的两个结构不兼容的初始化中。类型可以是...
这意味着投影中的属性必须以相同的顺序初始化,我如何通过自动映射器设置投影属性初始化顺序?
很晚的回答,简短的版本似乎是 "You can't"。
我有完全相同的问题 (Can I force Automapper to initialise properties in a certain order?),最终在 LINQ select 语句中映射了所有内容。
为方便起见,我在我的 DTO 中将其设为静态方法(缩减代码):
public static IQueryable<MyDto> QueryableFromTaskType1(
IQueryable<TaskType1> query)
{
return query.Select(src => new MyDto()
{
TaskId = src.Id,
AssetTypeName = src.Asset.AssetType.Name,
AssetId = src.Asset.Id,
AssetCode = src.Asset.Code,
AssetName = src.Asset.Name,
});
}
public static IQueryable<MyDto> QueryableFromTaskType2(
IQueryable<TaskType2> query)
{
return query.Select(src => new MyDto()
{
TaskId = src.Id,
AssetTypeName = src.AssetTypeName,
AssetId = src.AssetId,
AssetCode = src.AssetCode,
AssetName = src.AssetName,
});
}
然后你可以得到你的对象,作为一个 IQueryable,简单地通过适当的静态方法传递它们(它将 select 附加到 DTO - 或其他已知的项目中)然后 Union 或 Concat结果 IQueryables。
唯一的缺点是 Automapper 通常会处理递归自动映射,尽管我很确定无论如何都不会很好地映射到 SQL,所以您可能不会损失太多。