【发布时间】:2014-02-21 08:58:33
【问题描述】:
目前我们实现了一个这样的映射服务(该服务使用automapper,我们在这部分使用了它的投影功能)
// Injected
// IGenericRepository<Entity> entityRepo
var query = this.entityRepo
.FindAll(a => a.Id == someId)
.Take(1);
var result = this.mappingService
.Map<Entity, EntityDto>(query)
.FirstOrDefault();
我想创建一个允许我执行以下操作的扩展程序
var result = this.entityRepo
.FindAll(a => a.Id == someId)
.Take(1).Map<EntityDto>() <--- Entity inferred from repo type
.FirstOrDefault();
我目前的尝试:
public static class IQueryableExtensions
{
private static IMappingService mappingService;
// will need to be called in app initialization
public static void InitialiseMapper(IMappingService service)
{
mappingService = service;
}
public static IEnumerable<TDto> Map<TAttribute, TDto>(this IQueryable<TAttribute> value)
where TDto : class
where TAttribute : IEntity
{
return mappingService.Map<TAttribute, TDto>(value);
}
}
因此目前我的实现看起来像这样。
var result = this.entityRepo
.FindAll(a => a.Id == someId)
.Take(1).Map<Entity,EntityDto>()
.FirstOrDefault();
问题:
1) 我将如何从 IQueryable 对象推断实体类型
2) 我意识到在创建静态类时我无法创建带参数的构造函数。我初始化映射器的方式是最好/唯一的方式吗?
【问题讨论】:
-
我不知道是不是只有我,如果我读错了。你到底为什么要使用
.Take(1)和.FirstOrDefault(),你不能直接去.FirstOrDefault(a => a.Id == someId).Map<Entity, EntityDto>吗?你也不能改变你的Map()方法并将其更改为MapFirstOrDefault()并在你的帮助类中执行第一个或默认值,因为你已经完成了编写扩展方法的工作。 -
Take(1),仍将返回一个集合和 FirstOrDefault(),获取第一个项目并将其映射到您的实体类型。但是在这个例子中 Take(1), & FirstOrDefault() 与问题无关,只是作为查询的一个例子......因为我的问题与映射部分 EG 有关。 IQueryable
到 IEnumerable -
那么让我看看这次我做对了吗?所以你是说这段代码
return mappingService.Map<TAttribute, TDto>(value);没有返回IEnumerable<EntityDto>,但你希望它返回IEnuerable<EntityDto>? -
我想将调用语法从:.Map
(query) 更改为 .Map ()
标签: c# generics extension-methods automapper