問題描述
我正在使用 linq 過濾選擇的 MessageItem.我編寫的方法接受一堆可能為空的參數(shù).如果它們?yōu)榭眨瑒t應忽略文件的標準.如果不為空,就用它來過濾結(jié)果.
I'm using linq to filter a selection of MessageItems. The method I've written accepts a bunch of parameters that might be null. If they are null, the criteria for the file should be ignored. If it is not null, use it to filter the results.
我的理解是在做 || 時操作是 C#,如果第一個表達式為真,則不應計算第二個表達式.
It's my understanding that when doing an || operation is C#, if the first expression is true, the second expression should not be evaluated.
例如
if(ExpressionOne() || ExpressionTwo())
{
// only ExpressionOne was evaluated because it was true
}
現(xiàn)在,在 linq 中,我正在嘗試:
now, in linq, I'm trying this:
var messages = (from msg in dc.MessageItems
where String.IsNullOrEmpty(fromname) || (!String.IsNullOrEmpty(fromname) && msg.FromName.ToLower().Contains(fromname.ToLower()))
select msg);
我會認為這會是合理的,因為 String.IsNullOrEmpty(fromname)
將等于 true 和 || 的第二部分不會跑.
I would have thought this would be sound, because String.IsNullOrEmpty(fromname)
would equal true and the second part of the || wouldn't get run.
但是它確實運行了,第二部分
However it does get run, and the second part
msg.FromName.ToLower().Contains(fromname.ToLower()))
拋出一個空引用異常(因為fromname
為空)!!- 我收到一個經(jīng)典的對象引用未設(shè)置為對象的實例"異常.
throws a null reference exception (because fromname
is null)!! - I get a classic "Object reference not set to an instance of an object" exception.
有什么幫助嗎?
推薦答案
閱讀本文檔 解釋了 linq 和 c# 如何斷開連接.
Have a read of this documentation which explains how linq and c# can experience a disconnect.
由于希望將 Linq 表達式簡化為普通方法以外的其他內(nèi)容,因此您可能會發(fā)現(xiàn)此代碼稍后在某些非 Linq to Objects 上下文中使用時會中斷.
Since Linq expressions are expected to be reduced to something other than plain methods you may find that this code breaks if later it is used in some non Linq to Objects context.
說的是
String.IsNullOrEmpty(fromname) ||
( !String.IsNullOrEmpty(fromname) &&
msg.FromName.ToLower().Contains(fromname.ToLower())
)
格式錯誤,因為它應該是
Is badly formed since it should really be
String.IsNullOrEmpty(fromname) ||
msg.FromName.ToLower().Contains(fromname.ToLower())
這讓你很清楚你依賴 msg 和 msg.FromName 都是非空的.
which makes it nice and clear that you are relying on msg and msg.FromName to both be non null as well.
為了讓您在 C# 中的生活更輕松,您可以添加以下字符串擴展方法
To make your life easier in c# you could add the following string extension method
public static class ExtensionMethods
{
public static bool Contains(
this string self, string value, StringComparison comparison)
{
return self.IndexOf(value, comparison) >= 0;
}
public static bool ContainsOrNull(
this string self, string value, StringComparison comparison)
{
if (value == null)
return false;
return self.IndexOf(value, comparison) >= 0;
}
}
然后使用:
var messages = (from msg in dc.MessageItems
where msg.FromName.ContainsOrNull(
fromname, StringComparison.InvariantCultureIgnoreCase)
select msg);
然而這不是問題.問題在于系統(tǒng)的 Linq to SQL 方面正在嘗試使用 fromname
值來構(gòu)造發(fā)送到服務器的 query.
However this is not the problem. The problem is that the Linq to SQL aspects of the system are trying to use the fromname
value to construct the query which is sent to the server.
由于 fromname
是一個變量,所以翻譯機制會關(guān)閉并執(zhí)行要求的操作(即使它為 null,也會生成 fromname
的小寫表示,這會觸發(fā)例外).
Since fromname
is a variable the translation mechanism goes off and does what is asked of it (producing a lower case representation of fromname
even if it is null, which triggers the exception).
在這種情況下,您可以執(zhí)行您已經(jīng)發(fā)現(xiàn)的操作:保持查詢原樣,但確保您始終可以創(chuàng)建具有所需行為的非空 fromname 值,即使它為空.
in this case you can either do what you have already discovered: keep the query as is but make sure you can always create a non null fromname value with the desired behaviour even if it is null.
也許更好:
IEnumerable<MessageItem> results;
if (string.IsNullOrEmpty(fromname))
{
results = from msg in dc.MessageItems
select msg;
}
else
{
results = from msg in dc.MessageItems
where msg.FromName.ToLower().Contains(fromname)
select msg;
}
這并不是很好,因為查詢包含其他約束,從而導致更多的重復,但對于簡單的查詢,實際上應該導致更易讀/可維護的代碼.如果您依賴匿名類型,這會很痛苦,但希望這對您來說不是問題.
This is not so great it the query contained other constraints and thus invovled more duplication but for the simple query actually should result in more readable/maintainable code. This is a pain if you are relying on anonymous types though but hopefully this is not an issue for you.
這篇關(guān)于||(或)C# 中的 Linq 運算符的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!