在LINQ to Objects中,是否有无法识别哪些实体/对象在每个过滤器上合格/不合格?如何拦截Linq过滤器
对于EG)比方说,我有一个名为实体“产品”(编号,名称),如果我输入100个产品分为LINQ查询其具有5‘其中’条件及获得20种产品的输出。
有什么方法可以确定哪个产品在哪个条件下被过滤?
在LINQ to Objects中,是否有无法识别哪些实体/对象在每个过滤器上合格/不合格?如何拦截Linq过滤器
对于EG)比方说,我有一个名为实体“产品”(编号,名称),如果我输入100个产品分为LINQ查询其具有5‘其中’条件及获得20种产品的输出。
有什么方法可以确定哪个产品在哪个条件下被过滤?
重要的方面仍然是你想要对每个级别的过滤数据做什么,因为你会知道linq到对象,使用链接机制,其中一个级别的结果作为输入馈送到下一级别,有些像:
var result = OriginalList.Where(Condition1) - Level1
.Where(Condition2) - Level2
.Where(Condition3) - Level3
.Where(Condition4) - Level4
这里Level1的输出是Level2的输入,等等。如果在某个级别没有数据,如果将确保下一组级别在内部被跳过,因为空集合上的任何条件是空集。
在每个级别上得到一个结果,你需要将它们在不同的变量分离,做你自己的基础上,你可能有条件的要求,类似的链接:
var result1 = OriginalList.Where(Condition1)
var result2 = result1.Where(Condition2)
于是就和等等,在应用result1上的where子句之前,您可以应用条件检查。 据我了解,你可能需要一个标准的记录器在每个子点打印的细节,实现扩展方法如下:
public static class LoggingExtension
{
public static void Log<dynamic>(IEnumerable<dynamic> collection)
{
// Use the favorite logger to log the collection here
}
}
如果我使用上面的代码打印RESULT1,结果2,你需要什么是:
var result1 = OriginalList.Where(Condition1)
result1.Log();
var result2 = result1.Where(Condition2)
result2.Log();
我的扩展方法使用动态类型上面,避免提取一个匿名的类型,内部可以输入转换为任何类型,并在记录器
使用这大概可以被推广,但你可以做到 这个。我只是没有看到它的用例。
使用ToLookup()
来划分您的查询。 “不合格”项目将被集中在false
组下,您可以继续使用true
组进行查询。
例如,
var numbers = Enumerable.Range(0, 100);
var p1 = numbers.ToLookup(n1 => n1 < 50);
// p1[false] -> [ 50, 51, 52, ... ]
var p2 = p1[true].ToLookup(n2 => n2 % 2 == 0);
// p2[false] -> [ 1, 3, 5, 7, ... ]
var p3 = p2[true]... // and so on
正当众人到目前为止展示了如何做明显的事情,也就是将数据分组到匹配一个条件块,没有人讨论你实际上问
确定哪个产品得到过滤在哪条件下
坚韧q问题是如何记录哪里的条件?
这样做可能看起来微不足道,但是您将失败,因为您将无法获得所使用的Func
对象的字符串表示形式。它是一个代表,即编译后的代码,并且您必须在运行时对其进行反向工程以获取源代码。这本身就很难,但是如果编译器选择优化你丢失的代码。
只有当你愿意创建使用表达在Func
小号代替你就可以登录WHERE条件你自己的扩展方法(S),因为表达式包含令牌可以很容易地的'在运行时ToString-ed'。
例如:
public static IEnumerable<T> WhereEx<T>(this IEnumerable<T> sequence, Expression<Func<T, bool>> condition)
{
var logString = condition.Body.ToString();
foreach (T item in sequence.Where(condition.Compile()))
{
yield return item;
// logging hook here, this one simply dumps in Linqpad.
string.Format("Item '{0}' meets '{1}'", item, logString).Dump();
}
}
现在你真的拦截过滤器。但是你不知道过滤器在代码中的应用位置。如果您还想记录堆栈帧,性能可能会成为问题(反射!),因为每次编译表达式都已经承受了压力。然后日志应该是一个涉及线程安全日志队列的异步操作。
感谢您的回复 – memumani
是您在找什么? (另外,它看起来像你评论你的问题,而不是我的答案:P) –
感谢您的答复。各种查询都在我想记录这些信息的不同地方。而不是在多个地方进行更改是否有任何genralized的方法来保持它在一个地方或以最小的变化 – memumani