转换LamdaFunctions - Func <iqueryable <td>,IOrderedQueryable&gt;到Func <iqueryable <te>,IOrderedQueryable <te>&gt; </te> </iqueryable <te> </iqueryable <td>

时间:2014-07-03 09:23:43

标签: c# linq lambda

有没有办法将Func<IQueryable<TD>, IOrderedQueryable<TD>>转换为Func<IQueryable<TE>, IOrderedQueryable<TE>>

我们说我有课程国家和国家模型。

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。

可能存在一些语法错误。为此道歉。

3 个答案:

答案 0 :(得分:0)

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中定义explicitimplicit运算符以从国家/地区转换

答案 1 :(得分:0)

您可能会发现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();

答案 2 :(得分:0)

使用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);
    }
}