35

Próbuję zaimportować funkcję CONTAINS() SQL Server w moim modelu Entity Framework, aby móc jej używać w moich kwerendach LINQ.Importowanie CONTAINS() funkcji SQL Server jako funkcji zdefiniowanej w modelu

Dodałem to do mojego EDM:

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

dodawania stworzony moja metoda niedopałek:

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

próbuję wywołać funkcję tak:

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

Poniższy wyjątek jest podniesiony:

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

Zdaję sobie sprawę, że zdefiniowana przeze mnie funkcja nie jest bezpośrednio powiązana z kwestionowanym zestawem encji, co może być również problemem.

Czy istnieje sposób, aby to zrobić?

+0

Możliwy duplikat? http://stackoverflow.com/questions/224475/is-it-possible-to-use-full-text-search-fts-with-linq – Pondlife

+2

Sugerowanym rozwiązaniem w tym pytaniu jest import funkcji o wartości tabelarycznej, która działa dla LINQ do SQL, ale nie (aktualny) dla Entity Framework –

Odpowiedz

3

Funkcja zdefiniowano powyżej używa Entity SQL, nie Transact-SQL, więc myślę, że pierwszym krokiem jest dowiedzieć się, czy zawiera (*, „tekst”) może być wyrażona w Entity SQL.

Entity SQL nie obsługuje operator *, jak opisano tutaj: http://msdn.microsoft.com/en-us/library/bb738573.aspx i jeśli próbuję

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

otrzymuję ten sam błąd co masz powyżej. Jeśli próbuję jawnie przekazać kolumnę, to działa:

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

Ale kiedy patrzę na SQL, przetłumaczyłem go na wyrażenie 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]" 

Jeśli nie można wyrazić za pomocą Entity SQL kwerendy będziesz musiał użyć procedury przechowywanej lub inny mechanizm użyć Transact-SQL bezpośrednio.

1

To jest poza mną, ale można spróbować

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

Moje rozumowanie jest to, że w SQL Server to spodziewa się dwa parametry.

1

Wprowadziłem małą funkcję do mojego kodu, w klasie, która dziedziczy z klasy Context, która wskazuje na moją funkcję SQL obsługującą wyszukiwanie pełnotekstowe, moje rozwiązanie jest nieco bardziej zamknięte, zakończone na waszym (nie pozwalając na specyfikację typ wyszukiwania tekstowego), zwraca IEnumerable, zasadniczo listę podstawowych kluczy spełniających kryteria wyszukiwania, coś takiego;

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; 
      } 
}; 

użycie jest podobne;

myContext context = new myContext(); 

IEnumerable<int> series_identities = (from t1 in context.Search("some term") 
                select t1).Distinct(); 
Powiązane problemy