通常,我的存储库具有用于调试目的的日志记录语句,使我能够查看参数的值。最近,我沿着创建一个通用存储库的道路,该存储库将谓词表达式作为参数,以实现极大的灵活性,但是我无法找到一种将条件记录到远程有用的地方的体面方法。
示例方法:
public int GetCount<K>(Expression<Func<K, bool>> predicate) where K : class
{
Logger.LogDebugMessage(String.Format("Parameters [predicate: {0}]", predicate == null ? string.Empty : predicate.Body.ToString()));
...
}
您可以看到我此时正在使用 Body.ToString(),但结果不太可读:
Parameters [predicate: (fa.SomeId == value(NameSpace.SomeClass+) >c__DisplayClass2).SomeId)]
最终我希望看到的是类似于以下内容的内容:
Parameters [predicate: (fa.SomeId == 1 && fa.Account.Name = = "MyName").SomeId)]
本质上,该日志的价值在于能够在发生故障时知道输入值。
有没有办法解决这个问题,强制 API 用户以字符串形式提供谓词?
Typically my repositories have logging statements for debugging purposes, allowing me to see values of parameters. Recently I went down the path of creating a generic repository that take predicate Expression as argument for great flexibility, however I cannot figure out a decent way of logging the condition to where it would be remotely useful.
Example Method:
public int GetCount<K>(Expression<Func<K, bool>> predicate) where K : class
{
Logger.LogDebugMessage(String.Format("Parameters [predicate: {0}]", predicate == null ? string.Empty : predicate.Body.ToString()));
...
}
You can see I am using the Body.ToString() at this point, but the results are not-so-readble:
Parameters [predicate: (fa.SomeId == value(NameSpace.SomeClass+<>c__DisplayClass2).SomeId)]
Ultimately what I would love to see is something similar to the below:
Parameters [predicate: (fa.SomeId == 1 && fa.Account.Name == "MyName").SomeId)]
In essence the value of this log is being able to know the input values when something blows up.
Is there any way around this short of forcing the user of the API to supply the predicate as a string?
发布评论
评论(2)
Matt Warren 的这篇博客文章包含用变量名称替换局部变量引用的代码。因此,您将得到
predicate: (fa.SomeId == someValue),而不是
。predicate: (fa.SomeId == value(NameSpace.SomeClass+<>c__DisplayClass2).SomeId)
)博客文章:
http://blogs.msdn.com/b/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx
来源:
This blog post by Matt Warren contains code that replaces a local variable reference with the variable name. So, instead of
predicate: (fa.SomeId == value(NameSpace.SomeClass+<>c__DisplayClass2).SomeId)
, you will getpredicate: (fa.SomeId == someValue)
.The blog post:
http://blogs.msdn.com/b/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx
The source:
我曾经遇到过这个问题,并通过为所有可能被记录的谓词创建一个枚举来解决它,在我的例子中,这些谓词并不多。如果您的情况不是这样,只需为每个谓词创建一个枚举条目和一个
Dictionary, YourEnum>
,并记录枚举的值而不是谓词。I had this problem once, and solved it by creating an enum for all predicates that could possible be logged, which weren't that many in my case. If it isn't either in your case, just create one enum-entry per predicate and a
Dictionary<Predicate<T>, YourEnum>
, and log the value of the enum instead of the predicate.