How can I get all types participating in a linq expression? I actually need this to be able to cache the query results.
In this example it is easy:
var Query = (from x in DataContext.Current.ContractDurations select x);
as the type i need is provided in
Query.ElementType
But what happens when I do this:
var Query = (from x in Data开发者_如何转开发Context.Current.ContractDurations select x.ID);
The ElementType will be int. The same problem will exist with joins where the ElementType will be some random anonymous type.
I'm not seeing a problem here... As long as the original data context is IQueryable, you should have access to ElementType.
See the following:
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;
}
}
The key is that ElementType is a member of IQueryable, so you need to make sure that EITHER the original source is IQueryable (as in query1 and query2), OR that you cast the query to IQueryable (as in query3).
Finally, for this kind of thing, grab a copy of LinqPad... The free version is great, the paid version will give you intellisense.
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);
}
}
}
精彩评论