我試圖做到以下幾點:的LINQ to NHibernate的用戶定義的函數在where子句
var query =
(from a in session.Query<A>()
where a.BasicSearch(searchString) == true
select a);
但它不斷給我這個異常「System.NotSupportedException」!
任何想法如何解決這個問題?
我試圖做到以下幾點:的LINQ to NHibernate的用戶定義的函數在where子句
var query =
(from a in session.Query<A>()
where a.BasicSearch(searchString) == true
select a);
但它不斷給我這個異常「System.NotSupportedException」!
任何想法如何解決這個問題?
在LINQ查詢中不能使用用戶定義的函數。 NHibernate的linq提供者不知道如何將你的函數轉換成SQL。
LINQ to NHibernate通過檢查您在運行時提供的LINQ表達式,並將它在此表達式樹中發現的內容轉換爲常規SQL表達式。這裏有一篇很好的文章來獲得表達式樹的一些背景知識:http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx
但是,您可以使用techniques discussed here這種以其他方式重用謂詞。 (我不知道但是,如果這個工程與NHibernate)。如果它工作會是這個樣子:
// this could be a static method on class A
public static Expression<Func<A, bool>> BasicSearch(string criteria)
{
// this is just an example, of course
// NHibernate Linq will translate this to something like
// 'WHERE a.MyProperty LIKE '%@criteria%'
return a => criteria.Contains(a.MyProperty);
}
用法:
from a in Session.Query<A>().Where(A.BasicSearch(criteria))
更新:顯然會有與NHibernate的問題。見this blog post for a version that ought to work。
可以調用你自己的和SQL函數,但是你必須爲它們做一個包裝,這樣NHibernate纔會知道如何將C#轉換爲SQL。
Here's an example其中我寫了一個擴展方法來訪問SQL Server的NEWID()
函數。您可以使用相同的技術來訪問數據庫服務器上的任何其他功能,這些功能是內置的或用戶定義的。
這隻適用於'QueryOver'而不是'Query' – Rippo
聲明一個BasicSearch
擴展方法。假設你的UDF是DBO:
using NHibernate.Linq;
...
public static class CustomLinqExtensions
{
[LinqExtensionMethod("dbo.BasicSearch")]
public static bool BasicSearch(this string searchField, string pattern)
{
// No need to implement it in .Net, unless you wish to call it
// outside IQueryable context too.
throw new NotImplementedException("This call should be translated " +
"to SQL and run db side, but it has been run with .Net runtime");
}
}
然後用它在你的實體:
session.Query<A>()
.Where(a => a.SomeStringProperty.BasicSearch("yourPattern") == true);
當心,嘗試使用它,而不引用其使用的實體將使其獲得與.net評估而不是將其轉換爲SQL。
將此BasicSearch
示例改爲適用於任何必須處理的輸入類型。你的問題是直接調用它的實體,它不允許你的讀者知道需要運行多少列和哪些類型。
所以有沒有可能的方式來使用用戶定義的功能進行過濾? – Ruba
查看更新。不是直接的,但可以通過PredicateBuilder實現。 – jeroenh