Импорт SQL Server CONTAINS () в качестве функции, определенной моделью - PullRequest
35 голосов
/ 26 января 2012

Я пытаюсь импортировать функцию SQL Server CONTAINS () в мою модель Entity Framework, чтобы я мог использовать ее в своих запросах LINQ.

Я добавил это в мой 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 '*'

Я понимаю, что определенная мною функция не связана напрямую с запрашиваемым набором сущностей, поэтому это также может быть проблемой.

Есть ли способ справиться с этим?

Ответы [ 3 ]

3 голосов
/ 29 июня 2012

Функция, которую вы определили выше, использует Entity SQL, а не Transact SQL, поэтому я думаю, что первым шагом будет выяснить, можно ли CONTAINS (*, 'text') выразить в Entity SQL.

Entity 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]"

Если вы не можете выразить запрос с помощью Entity SQL, вам придется использовать хранимую процедуру или другой механизм для непосредственного использования Transact SQL.

1 голос
/ 23 мая 2012

Я вставил небольшую функцию в свой код, в класс, который наследуется от класса 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();
1 голос
/ 11 мая 2012

Это далеко от меня, но не могли бы вы попробовать

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

Я считаю, что в SQL Server он ожидает два параметра.

...