35

我想在我的實體框架模型中導入SQL Server的CONTAINS()函數,以便我可以在我的LINQ查詢中使用它。導入SQL Server的CONTAINS()作爲模型定義函數

我已經加入這個我EDM:

<Function Name="FullTextSearch" ReturnType="Edm.Boolean"> 
    <Parameter Name="Filter" Type="Edm.String" /> 
    <DefiningExpression> 
     CONTAINS(*, Filter) 
    </DefiningExpression> 
</Function> 

放入創造我的方法存根:

[EdmFunction("MyModelNamespace", "FullTextSearch")] 
public static bool FullTextSearch(string filter) 
{ 
    throw new NotSupportedException("This function is only for L2E query."); 
} 

我嘗試調用的函數是這樣的:

from product in Products 
where MyModel.FullTextSearch("FORMSOF(INFLECTIONAL, robe)") 
select product 

以下異常提出:

The query syntax is not valid. Near term '*' 

我意識到我定義的函數並沒有直接鏈接到被查詢的實體集,所以也可能是一個問題。

有什麼辦法可以解決這個問題嗎?

+0

可能重複? http://stackoverflow.com/questions/224475/is-it-possible-to-use-full-text-search-fts-with-linq – Pondlife

+2

這個問題的建議解決方案是導入一個表值函數,它適用於LINQ to SQL,但不適用於實體框架(當前) –

回答

3

你上面定義的函數使用實體SQL,尚未辦理SQL,所以我認爲第一步是要弄清楚是否包含(*,「文本」)可以在實體SQL表示。這裏描述

實體SQL不支持*操作:http://msdn.microsoft.com/en-us/library/bb738573.aspx如果我嘗試

entities.CreateQuery<TABLE_NAME>("select value t from TABLE_NAME as t where CONTAINS(*, 'text')"); 

我給你上面得到了同樣的錯誤。如果我試圖明確地傳遞它的工作原理柱:

entities.CreateQuery<TABLE_NAME>("select value t from TABLE_NAME as t where CONTAINS(t.COLUMN_NAME, 'text')"); 

但是,當我看着它的SQL它翻譯成LIKE的表達。

ADO.NET:Execute Reader "SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM [dbo].[TABLE_NAME] AS [Extent1] 
    WHERE (CASE WHEN ([Extent1].[COLUMN_NAME] LIKE '%text%') THEN cast(1 as bit) WHEN (NOT ([Extent1].[COLUMN_NAME] LIKE '%text%')) THEN cast(0 as bit) END) = 1 
) AS [GroupBy1]" 

如果無法使用實體SQL表達查詢,則必須使用存儲過程或其他機制來直接使用Transact SQL。

1

這是遠遠超越我,但你可以嘗試

from product in Products where MyModel.FullTextSearch(product, "FORMSOF(INFLECTIONAL, robe)") select product 

我的理由是,在SQL Server它期待兩個參數。

1

我在我的代碼中插入了一個小函數,它在繼承自Context類的類中,該類指向支持全文搜索的SQL函數,我的解決方案稍微封閉一點給你(不允許指定文本搜索的類型),它返回一個IEnumerable,本質上是一個匹配搜索條件的主鍵列表,如下所示;

public class myContext : DataContext 
{ 

    protected class series_identity 
    { 
      public int seriesID; 

      series_identity() { } 
    }; 

      [Function(Name = "dbo.fnSeriesFreeTextSearchInflectional", IsComposable = true)] 
      protected IQueryable<series_identity> SynopsisSearch([Parameter(DbType = "NVarChar")] string value) 
      { 
       return this.CreateMethodCallQuery<series_identity>(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), value); 
      } 

      public IEnumerable<int> Search(string value) 
      { 
       var a = from t1 in SynopsisSearch(value) 
         select t1.seriesID; 

       return a; 
      } 
}; 

用法類似於;

myContext context = new myContext(); 

IEnumerable<int> series_identities = (from t1 in context.Search("some term") 
                select t1).Distinct(); 
相關問題