El soporte de TVF ha sido uno de los elementos más demandados dentro de los foros y listas de insiders al grupo de ADO.NET. A pesar de que teníamos en EDM pequeños trucos con lo que podríamos hacer funcionar esta característica en 4.0, aunque seguro que todos los que habéis jugado con EDM sabéis que no es muy buena idea andar tocando a mano el XML subyacente, por no decir que es de lo más viscoso con lo que puedas encontrarte, el convertir a estas UDF’s en ciudadanos de primer nivel parecía algo necesario que por suerte tenemos ya disponible de forma idéntica a como usamos procedimientos almacenados en la actualidad. Por supuesto, no voy a hacer una introducción a las TVF’s, seguro que ya hay mucho contenido en internet sobre el asunto, por lo que lo único que diremos es que a grosso modo los TVF aúnan lo bueno de las vistas, la composición, y lo bueno de los procedimientos, que pueden contener código procedural, permitiéndonos ya sobre EF mezclarlas con L2E y ESQL, que es lo que a nosotros nos dará más valor todavía. Con el fin de mostrar un pequeño ejemplo partiremos de una sencilla tabla en la que tenemos un índice full text ,el script de esta tabla es el siguiente:
1 |
<span style="color: #0000ff">SET</span> ANSI_NULLS <span style="color: #0000ff">ON</span> |
1 |
<span style="color: #0000ff">GO</span> |
1 |
  |
1 |
<span style="color: #0000ff">SET</span> QUOTED_IDENTIFIER <span style="color: #0000ff">ON</span> |
1 |
<span style="color: #0000ff">GO</span> |
1 |
  |
1 |
<span style="color: #0000ff">CREATE</span> <span style="color: #0000ff">TABLE</span> [dbo].[book]( |
1 |
[id] [<span style="color: #0000ff">int</span>] <span style="color: #0000ff">IDENTITY</span>(1,1) <span style="color: #0000ff">NOT</span> <span style="color: #0000ff">NULL</span>, |
1 |
[name] [nvarchar](200) <span style="color: #0000ff">NOT</span> <span style="color: #0000ff">NULL</span>, |
1 |
[description] [nvarchar](<span style="color: #0000ff">max</span>) <span style="color: #0000ff">NOT</span> <span style="color: #0000ff">NULL</span>, |
1 |
[isbn] [nvarchar](15) <span style="color: #0000ff">NOT</span> <span style="color: #0000ff">NULL</span>, |
1 |
<span style="color: #0000ff">CONSTRAINT</span> [PK_book] <span style="color: #0000ff">PRIMARY</span> <span style="color: #0000ff">KEY</span> <span style="color: #0000ff">CLUSTERED</span> |
1 |
( |
1 |
[id] <span style="color: #0000ff">ASC</span> |
1 |
)<span style="color: #0000ff">WITH</span> (PAD_INDEX = <span style="color: #0000ff">OFF</span>, STATISTICS_NORECOMPUTE = <span style="color: #0000ff">OFF</span>, IGNORE_DUP_KEY = <span style="color: #0000ff">OFF</span>, ALLOW_ROW_LOCKS = <span style="color: #0000ff">ON</span>, ALLOW_PAGE_LOCKS = <span style="color: #0000ff">ON</span>) <span style="color: #0000ff">ON</span> [<span style="color: #0000ff">PRIMARY</span>] |
1 |
) <span style="color: #0000ff">ON</span> [<span style="color: #0000ff">PRIMARY</span>] |
1 |
  |
1 |
<span style="color: #0000ff">GO</span> |
Acto seguido, crearemos una también sencilla TVF que haga una query usando full text sobre la tabla anterior, por ejemplo, la siguiente udf.
1 |
<span style="color: #0000ff">CREATE</span> <span style="color: #0000ff">FUNCTION</span> [dbo].[BookFullText] |
1 |
(@text NVARCHAR(4000)) |
1 |
<span style="color: #0000ff">RETURNS</span> <span style="color: #0000ff">TABLE</span> |
1 |
<span style="color: #0000ff">RETURN</span> |
1 |
<span style="color: #0000ff">SELECT</span> isbn,name |
1 |
<span style="color: #0000ff">FROM</span> dbo.book |
1 |
<span style="color: #0000ff">WHERE</span> <span style="color: #0000ff">CONTAINS</span>([description], @text); |
Una vez hecho el trabajo, como comentábamos anteriormente, ya podemos mapear esta TVF dentro de nuestros modelos EDM igual que un procedimiento almacenado, para esto, sino sabe como, le recomiendo seguir la siguiente guía, y utilizarlos de diversas maneras, aunque mezclándolas con nuestras L2E es como se ve mejor el porque de la importancia de esta mejora.
A continuación se puede ver el uso de la función anterior:
1 |
var result = from author <span style="color: #0000ff">in</span> unitOfWork.Authors |
1 |
join books <span style="color: #0000ff">in</span> unitOfWork.BookFullText(<span style="color: #006080">"framework"</span>) |
1 |
on author.id equals books.Value |
1 |
select author; |
Que produciría la siguiente traza TSQL
1 |
<span style="color: #0000ff">exec</span> sp_executesql N<span style="color: #006080">'SELECT |
1 |
[Extent1].[id] AS [id], |
1 |
[Extent1].[name] AS [name] |
1 |
FROM [dbo].[Author] AS [Extent1] |
1 |
INNER JOIN [dbo].[BookFullText](@text) AS [Extent2] ON [Extent1].[id] = [Extent2].[id]'</span>,N<span style="color: #006080">'@text nvarchar(4000)'</span>,@text=N<span style="color: #006080">'framework'</span> |
Bueno, aquí termina esta entrada…
Saludos
Unai