2012-12-03 79 views

回答

6

在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

+0

所以有沒有可能的方式來使用用戶定義的功能進行過濾? – Ruba

+0

查看更新。不是直接的,但可以通過PredicateBuilder實現。 – jeroenh

1

可以調用你自己的和SQL函數,但是你必須爲它們做一個包裝,這樣NHibernate纔會知道如何將C#轉換爲SQL。

Here's an example其中我寫了一個擴展方法來訪問SQL Server的NEWID()函數。您可以使用相同的技術來訪問數據庫服務器上的任何其他功能,這些功能是內置的或用戶定義的。

+0

這隻適用於'QueryOver'而不是'Query' – Rippo

0

聲明一個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示例改爲適用於任何必須處理的輸入類型。你的問題是直接調用它的實體,它不允許你的讀者知道需要運行多少列和哪些類型。

相關問題