如何让类型参与表达式

本文关键字:表达式 类型 | 更新日期: 2023-09-27 18:06:54

如何获得参与linq表达式的所有类型?我实际上需要这个来缓存查询结果。

在这个例子中很简单:

var Query = (from x in DataContext.Current.ContractDurations select x);

我需要的类型在

中提供
Query.ElementType

但是当我这样做时会发生什么呢?

var Query = (from x in DataContext.Current.ContractDurations select x.ID);

ElementType将是int。如果ElementType是某种随机的匿名类型,那么在连接中也会出现同样的问题。

如何让类型参与表达式

我看不出有什么问题…只要原始数据上下文是IQueryable,就应该可以访问ElementType。

参见以下内容:

void Main()
{
    List<Alerts> alerts = new List<Alerts>();
    alerts.Add(new Alerts(DateTime.Now.AddDays(-1)));
    alerts.Add(new Alerts(DateTime.Now));
    IQueryable<Alerts> qAlerts = alerts.AsQueryable();
    var query1 = qAlerts.Select (a => a.Begins);
    Console.WriteLine(query1.ElementType);
    var query2 = qAlerts.Select (a => a);
    Console.WriteLine(query2.ElementType);
    var query3 = alerts.Select (a => a);
    Console.WriteLine(query3.AsQueryable().ElementType);
}
public class Alerts
{
    public DateTime Begins {get; set;}
    public Alerts(DateTime begins)
    {
        Begins = begins;
    }
}

关键是ElementType是IQueryable成员,因此您需要确保原始源是IQueryable(如query1和query2),或者您将查询强制转换为IQueryable(如query3)。

最后,对于这种事情,拿一个LinqPad的副本…免费版很棒,付费版会让你更有智慧。

 public class QueryExpressionVisitor : ExpressionVisitor
{
    public List<Type> Types
    {
        get;
        private set;
    }

    public QueryExpressionVisitor()
    {
        Types = new List<Type>();
    }
    public override Expression Visit(Expression node)
    {
        return base.Visit(node);
    }
    protected override Expression VisitConstant(ConstantExpression node)
    {
        if (node.Type.IsGenericTypeDefinition && node.Type.GetGenericTypeDefinition() == typeof(IQueryable<>))
            CheckType(node.Type.GetGenericArguments()[0]);
        return base.VisitConstant(node);
    }
    protected override Expression VisitMember(MemberExpression node)
    {
        CheckType(node.Member.DeclaringType);
        return base.VisitMember(node);
    }

    private void CheckType(Type t)
    {
        if (!Types.Contains(t))
        {
            Types.Add(t);
        }
    }
}