Подтвердить что ты не робот

Импортирование SQL Server CONTAINS() в качестве определенной модели

Я пытаюсь импортировать функцию 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 '*'

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

Есть ли способ снять это?

4b9b3361

Ответ 1

В приведенной выше функции используется 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.

Ответ 2

Это вне меня, но вы можете попробовать

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

Мое рассуждение заключается в том, что в SQL Server ожидается два параметра.

Ответ 3

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