C# 非专利药及;静态类。实现查询助手方法
目前,我们实现了这样一个映射服务(该服务使用automapper,我们在这一部分中使用了它的投影功能)C# 非专利药及;静态类。实现查询助手方法,c#,generics,extension-methods,automapper,C#,Generics,Extension Methods,Automapper,目前,我们实现了这样一个映射服务(该服务使用automapper,我们在这一部分中使用了它的投影功能) //注入 //IGenericRepository entityRepo var query=this.entityRepo .FindAll(a=>a.Id==someId) .采取(1)项措施; var result=this.mappingService .Map(查询) .FirstOrDefault(); 我想创建一个扩展,允许我执行以下操作 var result = this.e
//注入
//IGenericRepository entityRepo
var query=this.entityRepo
.FindAll(a=>a.Id==someId)
.采取(1)项措施;
var result=this.mappingService
.Map(查询)
.FirstOrDefault();
我想创建一个扩展,允许我执行以下操作
var result = this.entityRepo
.FindAll(a => a.Id == someId)
.Take(1).Map<EntityDto>() <--- Entity inferred from repo type
.FirstOrDefault();
var result=this.entityRepo
.FindAll(a=>a.Id==someId)
.Take(1.Map()a.Id==someId)
.Take(1.Map)()
.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);
}
}
1) 如何从IQueryable对象推断实体类型
2) 我意识到在创建静态类时,我不能创建一个带参数的构造函数。我初始化映射器的方法是最好的/唯一的方法吗?1)目前,在C#中根本无法做到这一点。类型推断不够好。可以指定所有类型参数,也可以不指定任何类型参数
编辑:如果您真的希望版本具有单个参数,则必须删除第二个类型参数,将该参数键入非泛型IQueryable
,然后处理它。一种方法是在运行时确定泛型IQueryable
类型。然而,这需要反思。对于IQueryable
,您还可以使用查询提供程序绕过反射
2) 您可以使用静态类型构造函数
public static class MyExtensions {
static MyExtensions() {
//initialization goes here
}
}
这种类型的构造函数甚至被称为线程安全的。但是,如果您设法在此处引发异常,则无法访问
MyExtensions
类 我试着反省一下。这些约束仅用于演示。如果要多次调用反射代码,请确保缓存最终的methodinfo
void Main()
{
var a = new Entity[] {new Entity { name = "a"},new Entity { name = "b"}};
Console.WriteLine(a.Take(1).Map<EntityDto>());
}
public class Entity
{
public string name;
}
public class EntityDto
{
public string dtoname;
}
public static class EntityExtensions
{
public static IEnumerable<U> Map<T,U>(this IEnumerable<T> e) where T: Entity where U: EntityDto, new()
{
foreach(var a in e)
{
yield return new U() { dtoname = a.name };
}
}
public static IEnumerable<U> Map<U>(this IEnumerable<object> e)
{
var method = typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.Name == "Map" && m.GetGenericArguments().Length == 2)
.Single();
method = method.MakeGenericMethod(e.GetType().GetGenericArguments()[0], typeof(U));
return method.Invoke(null, new object[] { e}) as IEnumerable<U>;
}
}
void Main()
{
var a=新实体[]{new Entity{name=“a”},新实体{name=“b”};
Console.WriteLine(a.Take(1.Map());
}
公共类实体
{
公共字符串名称;
}
公共类实体
{
公共字符串dtoname;
}
公共静态类EntityExtensions
{
公共静态IEnumerable映射(此IEnumerable e),其中T:Entity,其中U:EntityDto,new()
{
foreach(e中的var a)
{
返回新的U(){dtoname=a.name};
}
}
公共静态IEnumerable映射(此IEnumerable e)
{
var method=typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m=>m.Name==“Map”&&m.GetGenericArguments().Length==2)
.Single();
method=method.MakeGenericMethod(e.GetType().GetGenericArguments()[0],typeof(U));
作为IEnumerable返回方法.Invoke(null,新对象[]{e});
}
}
我不知道是否只有我一个人,也不知道我是否看错了。你到底为什么要使用.Take(1)
和.FirstOrDefault()
,难道你不能直接使用.FirstOrDefault(a=>a.Id==someId).Map
?您也不能更改Map()
方法并将其更改为MapFirstOrDefault()
,然后在助手类中执行第一个或默认值,因为您已经完成了编写扩展方法的工作。Take(1),仍将返回集合和FirstOrDefault(),获取第一个项并将其映射到您的实体类型。但在本例中,Take(1),&FirstOrDefault()与问题无关,只是作为查询的一个示例。。。由于我的问题与映射部分有关,例如IQueryable to IEnumerableSo,让我看看这次是否正确?你的意思是,这个代码返回mappingService.Map(value)
没有返回一个IEnumerable
,但您希望它返回IEnumerable
?我想将调用语法从:.Map(查询)更改为.Map()。查询提供程序的方法类似于
public static class MyExtensions {
static MyExtensions() {
//initialization goes here
}
}
void Main()
{
var a = new Entity[] {new Entity { name = "a"},new Entity { name = "b"}};
Console.WriteLine(a.Take(1).Map<EntityDto>());
}
public class Entity
{
public string name;
}
public class EntityDto
{
public string dtoname;
}
public static class EntityExtensions
{
public static IEnumerable<U> Map<T,U>(this IEnumerable<T> e) where T: Entity where U: EntityDto, new()
{
foreach(var a in e)
{
yield return new U() { dtoname = a.name };
}
}
public static IEnumerable<U> Map<U>(this IEnumerable<object> e)
{
var method = typeof(EntityExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(m => m.Name == "Map" && m.GetGenericArguments().Length == 2)
.Single();
method = method.MakeGenericMethod(e.GetType().GetGenericArguments()[0], typeof(U));
return method.Invoke(null, new object[] { e}) as IEnumerable<U>;
}
}