我有这个方法:
public List<object> GetThings(List<Guid> listOfGuids)
{
var query = serviceContext.Xrm.crmEntity;
bool anyTypeOfSearch = false; // use this to know if we have actually applied any search criteria.
if(listOfGuids != null && listOfGuids.Count > 0)
{
query = query.Where(x => listOfGuids.Contains(x.lgc_muncipalityid.Id));
anyTypeOfSearch = true;
}
var result = new List<object>();
if(anyTypeOfSearch) // instead of a variable here, can i check if there are any whereconditions applied to the query?
result = query
.Select(x => new SupplierSearchResultModel()
{
Id = x.Id,
Name = x.lgc_name,
})
.ToList();
LogMessage("GetThings.Query", <insert code to get query.Where condition tostring()>);
return result;
}
在实际代码中,有几个不同的if结构,其中包含.Where
条件,有时调用可以在没有任何参数的情况下到达此代码。在这种情况下,我不想运行查询,因为结果集将是巨大的。所以我只想在至少一次应用.Where()
条件后运行查询。
现在我的问题是,我是否可以检查一个lambda查询变量,看它是否应用了.Where()
条件而不使用像我这样的外部bool?
另一个有趣的使用点是,如果有某种方法可以获得某种query.Where().ToString()
方法,该方法将显示将应用哪些条件,以便在出现错误时记录...
答案 0 :(得分:3)
快速&amp;脏,如果你不关心有一个漂亮的结果:
LogMessage(query.Expression.ToString());
但它不会向您显示数组参数的内容。
编辑更好的解决方案:
1)您正在寻找的是表达访问者。 want to do here的模板,然后应该使用它:
LogMessage(query.ToPrettyString());
2)想一个表达式query.Where(x=>x.member == GetSomething())
你想要它被打印出来吗?或者您希望GetSomething()
结果显示为字符串结果?如果是第二个解决方案,那么你可以做with this
答案 1 :(得分:1)
您可以创建自己的ExpressionVisitor
实现来遍历表达式的节点。你可以这样做:
public class WhereVisitor : ExpressionVisitor
{
private static bool _filter;
private static WhereVisitor _visitor = new WhereVisitor();
private WhereVisitor() { }
public new static bool Visit(Expression expression)
{
_filter = false;
//Cast to ExpressionVisitor to use the default Visit and not our new one
((ExpressionVisitor)_visitor).Visit(expression);
return _filter;
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.Name == "Where")
_filter = true;
return base.VisitMethodCall(node);
}
}
并像这样使用它:
bool containsWhere = WhereVisitor.Visit(query.Expression);
如果你想要,你当然可以扩展访问者以保存包含Where
子句的表达式,但是这个只会告诉你是否有Where
。