views:

130

answers:

5

I have the following TVF for fulltext search:

FUNCTION [dbo].[Fishes_FullTextSearch]
(@searchtext nvarchar(4000), @limitcount int)
RETURNS TABLE
AS
RETURN 
SELECT * FROM Fishes
INNER JOIN CONTAINSTABLE(Fishes, *, @searchtext, @limitcount)
AS KEY_TBL ON Fishes.Id = KEY_TBL.[KEY]

When I'm using this TVF, it doesn't return a collection of objects of type Fish (which I want!) - instead LINQ creates a new result type which includes all "Fish" fields and the fields Key and Rank.

In another question, it was suggested that I rewrite this TVF into a stored procedure for it to return Fish objects only. Can someone help me do this please? Also, it needs to be ordered by Rank.

Edit: I need objects of type "Fish" only, without Key or Rank. Otherwise LINQ will create a new return type which I can't use easily with my existing code.

Thank you!

+1  A: 

Sure - no problem:

CREATE PROCEDURE [dbo].[Fishes_FullTextSearch]
       @searchtext nvarchar(4000), 
       @limitcount int
AS 
  SELECT Fishes.*
  FROM dbo.Fishes
  INNER JOIN CONTAINSTABLE(Fishes, *, @searchtext, @limitcount) AS KEY_TBL 
      ON Fishes.Id = KEY_TBL.[KEY]

That should return the same results, as the result set from the stored procedure.

marc_s
So now it will return objects of type Fish only? (No more Key and Rank)
Alex
@Alex: if you only need columns from the "Fishes" table, you'll have to use a `SELECT Fishes.* ....` statement (adapted my post accordingly).
marc_s
+2  A: 

You mean like this?

CREATE PROCEDURE [dbo].[Fishes_FullTextSearch]
    @searchtext nvarchar(4000),
    @limitcount int
AS
SELECT Fishes.* FROM Fishes
  INNER JOIN CONTAINSTABLE(Fishes, *, @searchtext, @limitcount)
  AS KEY_TBL ON Fishes.Id = KEY_TBL.[KEY]
  ORDER BY KEY_TBL.[Rank]

Update: (following comments and update to question)

Added order by clause and restricted return values to be from Fishes only. Assumes that Rank is a field name on the aliased KEY_TBL.

Oded
I don't think this is complete yet... 1) I don't want Rank and Key to be returned, 2) I need it ordered by Rank, and 3) I need LINQ to consider the result type of type Fish (and not some arbitrary new SP result return type).
Alex
@Alex - updated answer. You really should state _all_ of your requirements when you first ask the question, or you will get lots of irrelevant answers.
Oded
@oded I had that requirement in my original question: "(...)for it to return Fish objects only. (...) it needs to be ordered by Rank." I just pointed it out again in my edit because it appeared nobody read the whole question... Thanks for your help!
Alex
@Alex - SQL does not return Objects. It returns table rows. Linq2Sql converts these into objects - guess it wasn't originally that clrea.
Oded
@Oded of course. I said 'objects' to clarify that I was caring about the LINQ output.
Alex
+1  A: 

Also, it needs to be ordered by Rank.

CREATE PROCEDURE [dbo].[Fishes_FullTextSearch]
@searchtext nvarchar(4000),
@limitcount int
AS

SELECT Fishes.* 
FROM Fishes
INNER JOIN CONTAINSTABLE(Fishes, *, @searchtext, @limitcount) AS KEY_TBL ON Fishes.Id = KEY_TBL.[KEY]
ORDER BY Fishes.Rank

EDIT Guided by comment.

eKek0
Same problem as the other results - I need the return type to be "Fish" in LINQ. The "Fish" domain object doesn't have the properties Rank and Key as returned from Containstable. So I need to return objects without those properties so LINQ can identify the return type as "Fish".
Alex
A: 
Create Procedure dbo.Fishes_FullTextSearch
       @searchtext nvarchar(4000)
       , @limitcount int
AS 
  Select Fishes.Col1, Fishes.Col2, ...
  From dbo.Fishes
    Join ContainsTable(Fishes, *, @searchtext, @limitcount) AS FreeTextTable
      On Fishes.Id = FreeTextTable.Key
  Order By FreeTextTable.Rank

You shouldn't use Select * but instead should enumerate the columns you want. Thus, if you only want columns from the Fishes table, only specify columns from the Fishes table in the Select clause.

Thomas
Even though `SELECT *` is generally inadvisable, the "Fish object" is coupled tightly to the table definition; so this looser coupling will create problems for him when the table definition changes.
egrunin
@egrunin - NO! If the table definition changes, the stored proc will not necessarily be recompiled and Select * will not return the correct result. If the schema changes, the stored proc should be updated to account for the new changes.
Thomas
@egrunin -It might be the case in more recent versions of SQL Server that the compilation problem has been resolved. In older versions, once a view or sp was compiled, it converted * into the columns in the table. If the columns changed, the view or sp would not reflect the changes. Still, procedures and udfs should be treated like schema and should be updated in tandem with the table schema.
Thomas
@Thomas - I'm afraid we're both right: neither solution saves him from having to do a code review if he adds a db column.
egrunin
+1  A: 

The simplest answer to your first question: change

SELECT * FROM Fishes

to

SELECT Fishes.* FROM Fishes
egrunin