我正在嘗試使用表達式創建動態nhibernate查詢。我對Contains,StartsWith和EndsWith這些函數沒有任何問題,但我似乎無法使它與IsNullOrEmpty一起使用。下面是一些背景:使用String.IsNullOrEmpty(string)和Nhibernate創建動態Linq表達式
包含:
MethodInfo contains = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
ParameterExpression param = Expression.Parameter(typeof(MyType), "x");
Expression expression = null;
PropertyInfo info = typeof(MyType).Property("MyStringProperty");
expression = Expression.Property(param, info);
expression = Expression.Call(expression, info, Expression.Constant("Does it contain this string", typeof(string)));
在這一切結束時,表情是在調試器等於此:
expression = { x.MyStringProperty };
然後我把它變成一個lambda exrpression:
var finalExpression = Expression.Lambda<Func<MyType, bool>>(expression, param);
在這最後,finalExpression是這樣的:
x => x.MyStringProperty.Contains("Does it contain this string");
當我通過nhibernate運行它時,它正是我想要的。隨着IsNullOrEmpty雖然,這是我所:
MethodInfo isNull = typeof(string).GetMethod("IsNullOrEmpty", new Type[] { typeof(string) });
ParameterExpression param = Expression.Parameter(typeof(MyType), "x");
PropertyInfo info = typeof(MyType).GetProperty("MyStringProperty");
expression = Expression.Property(param, info);
expression = Expression.Call(isNull, expression);
在這一切結束時,表達等於:
expression = { IsNullOrEmpty(x.MyStringProperty) }
和之後的拉姆達轉換就變成:
finalExpression = { x => IsNullOrEmpty(x) }
這看起來完全像它應該(雖然我承認也許它應該讀取string.IsNullOrEmpty(x)),但是當我通過nhibernate運行它時,出現錯誤:
NotSupportedException
Message: Boolean IsNullOrEmpty(System.String)
有誰知道這是爲什麼?如果我運行一個沒有動態查詢和手工編寫一個地方像這樣的條款,它的工作原理沒有問題:
nhibernateDataProvider.Where(x => string.IsNullOrEmpty(x.MySTringProperty));
任何人都知道這是爲什麼/如何解決這一問題?
編輯:
爲什麼我試圖做到這一點:
在我的web層我必須向用戶顯示這個x.MyStringProperty數據。他們有能力通過這個屬性進行過濾,我希望能夠通過這些字符串方法來過濾數據。網絡層簡單地將這些功能向後:
BeginsWith
EndsWith
Contains
IsNullOrEmpty
NotIsNullOrEmpty
從這些名稱我可以直接把它們變成使用上述代碼串的方法。正因爲如此,我可以傳遞我的web圖層中的任何類型,並且能夠過濾任何字符串屬性。這非常強大,因爲對於我所有的數百個類,我可以有一個方法來處理每個類的過濾。正如我之前所說的,它可以用在非靜態的方法,因爲內置的表達式爲:
x -> x.MyStringProperty.NonStaticMethod("SomeFilterValue");
是說,對Expression.Call文檔權,你應該能夠用靜態方法來做到這一點。由於它適用於非靜態方法,必須有一種方法做IsNullOrEmpty使得表達變得
x -> string.StaticMethod(x.MyStringProperty)
我敢打賭你,如果我創建表達
x -> x.MySTringProperty == null || x.MySTringProperty == ""
它會工作,但也就是一個工作,作爲一名程序員,我覺得出於原則,我需要找出如何使用靜態方法來完成上述操作。
我非常感謝您的回覆。我編輯了上述內容,爲您提供更多信息。上面的解決方案可能會工作,我很快就會檢查出來,但也許您在編輯中也有問題的答案。 – Magn3s1um
我其實使用非常相似的邏輯。我的意思是,綁定服務器上的Filter對象,然後將其轉換爲Restrictions(Criteria API)。我會說,它可以以類似的方式用於你的情況。怎麼運行的?不是構建表達式,而是通過幾個擴展方法傳遞Criteria。如果它們中的任何一個能夠正確讀取過濾器,則附加限制。限制對字符串有很強的支持,所以如果我在過濾器綁定上應用足夠的驗證,我可以使用字符串。也許這可能會有所幫助,但它不是靜態方法的表達式生成器的答案;) –
我們從標準切換到Linq到nhibernate,所以表達式是必需的。我會看看== null || 「」解決方案有效。我會回覆結果,如果有效,我會給你答案。再次感謝 – Magn3s1um