简体   繁体   中英

Can I pass an IQueryable<> to a table valued function?

I have something like the following table to search some text:

SearchedTextTable
Id int primary key
Text nvarchar(max)
Code int

The Text is full text indexed, so I made the following table valued function to work with LinqToSQL:

ALTER FUNCTION [dbo].[SearchText] (@keywords nvarchar(4000))
returns @results table (Id int not null)
as
begin   
    INSERT @results
        SELECT 
            Id
        from SearchedTextTable
        where contains(Text,@keywords)  
    return;
end;

What I want to do is apply some conditions before searching text, like the following code:
NOTE: The conditions is actually kind of complex, so I don't want to put them into the table valued function.

using(var contetxt= new FooDataContext())
{
 var list = context.SearchedTextTable.Where(x => x.Code==code);
 var results = context.SearchText(list, keywords).ToList();
}

And The SearchText function should be like the following:

ALTER FUNCTION [dbo].[SearchText] (@table table, @keywords nvarchar(4000))
returns @results table (Id int not null)
as
begin   
    INSERT @results
        SELECT 
            Id
        from @table
        where contains(Text,@keywords)  
    return;
end;

Is this possible? If so could you tell me how?

Thanks in advance,
Yoo

EDIT

After some tests, seems the performance isn't affected anything even if I set some conditions before doing full text search. Both of them return less than 10ms.

You can join to your SearchText function or otherwise use it in a WHERE clause. I am not sure the syntax for linq-to-sql though.

If you change your function from a Multi-statement Table Valued Function to an Inline Table-Valued Function it would be a little better because the query optimizer will be able to optimize it better. An Inline Table-Valued Function works as if it were a View that accepted parameters.

ALTER FUNCTION [dbo].[SearchText] (@keywords nvarchar(4000))
RETURNS TABLE
RETURN
SELECT Id
FROM SearchedTextTable
WHERE contains(Text,@keywords);

So you want your linq-to-sql to generate some SQL similar to:

SELECT ... FROM SearchedTextTable 
WHERE code = 'x' AND Id IN (SELECT Id FROM SearchText('keyword'));

or

SELECT ... FROM SearchedTextTable AS A 
JOIN dbo.SearchText('keyword') AS B ON A.Id = B.Id 
WHERE A.code = 'x';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM