Linq - 如何获取参与表达式的类型

时间:2011-08-26 06:33:50

标签: c# linq

如何让所有类型参与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将是一些随机匿名类型。

2 个答案:

答案 0 :(得分:0)

我没有在这里看到问题...只要原始数据上下文是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)。 / p>

最后,对于这种事情,抢一份LinqPad ...免费版本很棒,付费版本会给你智能感知。

答案 1 :(得分:0)

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