2015-08-16 151 views
0

在LINQ to Objects中,是否有无法识别哪些实体/对象在每个过滤器上合格/不合格?如何拦截Linq过滤器

对于EG)比方说,我有一个名为实体“产品”(编号,名称),如果我输入100个产品分为LINQ查询其具有5‘其中’条件及获得20种产品的输出。

有什么方法可以确定哪个产品在哪个条件下被过滤?

+0

感谢您的回复 – memumani

+0

是您在找什么? (另外,它看起来像你评论你的问题,而不是我的答案:P) –

+0

感谢您的答复。各种查询都在我想记录这些信息的不同地方。而不是在多个地方进行更改是否有任何genralized的方法来保持它在一个地方或以最小的变化 – memumani

回答

0

重要的方面仍然是你想要对每个级别的过滤数据做什么,因为你会知道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(); 

我的扩展方法使用动态类型上面,避免提取一个匿名的类型,内部可以输入转换为任何类型,并在记录器

2

使用这大概可以被推广,但你可以做到 这个。我只是没有看到它的用例。

使用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 
0

正当众人到目前为止展示了如何做明显的事情,也就是将数据分组到匹配一个条件块,没有人讨论你实际上问

确定哪个产品得到过滤在哪条件下

坚韧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(); 
    } 
} 

现在你真的拦截过滤器。但是你不知道过滤器在代码中的应用位置。如果您还想记录堆栈帧,性能可能会成为问题(反射!),因为每次编译表达式都已经承受了压力。然后日志应该是一个涉及线程安全日志队列的异步操作。