Convert LamdaFunctions - Func<IQueryable<TD>, IOrde

本文关键字:lt gt IOrde TD IQueryable Convert LamdaFunctions Func | 更新日期: 2023-09-27 18:11:20

是否有办法将Func<IQueryable<TD>, IOrderedQueryable<TD>>转换为Func<IQueryable<TE>, IOrderedQueryable<TE>> ?

假设我有两个类Country和CountryModel。

class CountryModel
{
 public string Name {get;set;}
}
class Country{
 public string Name{get;set;}
}
class Repo{
 public IEnumerable<TD> Get(
            Func<IQueryable<TD>, IOrderedQueryable<TD>> orderBy = null)
{
  IQueryable<TEntityModel> query = CurrentDbSet;
  return orderBy(query).ToList(); // Convert orderBy to TE.
}
}

使用上面的方法,我将传递CountryModel实例。但是查询必须以实体类型Country进行。

可能有一些语法错误。很抱歉。

Convert LamdaFunctions - Func<IQueryable<TD>, IOrde

public class Repo
{
    public IEnumerable<TD> Get<TD, TE>(Func<IQueryable<TD>, IOrderedQueryable<TD>> orderBy = null)
    {
        IQueryable<TD> query = new List<TE>().Select(t => Convert<TD, TE>(t)).AsQueryable();
        return orderBy(query).AsEnumerable(); // Convert orderBy to TE.
    }
    public TD Convert<TD, TE>(TE input) where TD : class
    {
        return input as TD;
    } 
}

如果你的TE类型可以被强制转换为TD类型,这应该可以工作。

您可以在CountryModel中定义显式或隐式操作符来从Country

进行转换。

您可能会发现AutoMapper非常有用。

public static class MappingExtensions
{
    static MappingExtensions()
    {
        Mapper.CreateMap<CustomAlerts, Domain.Models.CustomAlerts>();
        Mapper.CreateMap<Domain.Models.CustomAlerts, CustomAlerts>();
        //add mappings for each set of objects here. 
        //Remember to map both ways(from x to y and from y to x)
    }
    //map single objects
    public static TDestination Map<TSource, TDestination>(TSource item)
    {
        return Mapper.Map<TSource, TDestination>(item);
    }
    //map collections
    public static IEnumerable<TDestination> Map<TSource, TDestination>(IEnumerable<TSource> item)
    {
        return Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>(item);
    }
}

然后在我的代码中,我可以做以下操作:

var TodayDate = DateTime.Now.AddDays(1);
        var Alerts = DB.CustomAlerts
                       .Where(x => x.EndDate >= TodayDate)
                       .OrderByDescending(x => x.DateCreated)
                       .Skip(((id - 1) * 50))
                       .Take(50);
        return Mapping.MappingExtensions.Map<CustomAlert,Models.CustomAlert>(Alerts).ToList();

使用AutoMapper和包装你的FuncExpression应该帮助你:

// Initialize AutoMapper
Mapper.Initialize(cfg => 
{ 
    cfg.CreateMap<TE, TD>();
    cfg.CreateMap<TD, TE>();
});
public class Repo
{
    // Wrap Func with Expression
    public IEnumerable<TD> Get(Expression<Func<IQueryable<TD>, IOrderedQueryable<TD>>> orderBy = null)
    {
        var orderByExpr = Mapper.Map<Expression<Func<IQueryable<TE>, IOrderedQueryable<TE>>>>(orderBy);            
        IQueryable<TE> query = CurrentDbSet;
        // Compile expression and execute as function 
        var items = orderByExpr.Compile()(query).ToList();
        // Map back to list of TD
        return Mapper.Map<IEnumerable<TD>>(items);
    }
}