É comum existirem stored procedures que retornam mais de um result set tal como o exemplo abaixo.
CREATE PROCEDURE [dbo].[ListCustomersAndEmployees] AS BEGIN SET NOCOUNT ON; SELECT * FROM dbo.Customers SELECT * FROM dbo.Employees END
Obs: Estou considerando que todos conhecem o banco de dados Northwind da Microsoft. Para fazer o download do mesmo veja no final do post.
O LINQ To SQL realiza o mapeamento da stored procedure da seguinte maneira.
[Function(Name="dbo.ListCustomersAndEmployees")] public ISingleResult<ListCustomersAndEmployeesResult> ListCustomersAndEmployees() { IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))); return ((ISingleResult<ListCustomersAndEmployeesResult>)(result.ReturnValue)); }
O problema é que no código acima só conseguimos adquirir os campos retornados pela primeira consulta, ou seja, os campos da tabela Customers.
Para resolver esse problema podemos utilizar o mecanismo de partial classes para criar um novo método que irá mapear a stored procedure. Esse mecanismo nos permite dividir a declaração de uma classe em múltiplos arquivos e isso é interessante, já que não é recomendado alterar o código gerado automaticamente pelo Visual Studio.
A idéia então é criar um novo arquivo que adiciona um novo método ao contexto. No exemplo abaixo o meu contexto possui o nome NorthwindDataContext.
public partial class NorthwindDataContext { [Function(Name = "dbo.ListCustomersAndEmployees")] [ResultType(typeof(Customer))] [ResultType(typeof(Employee))] public IMultipleResults ListMultipleCustomersAndEmployees() { IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod()))); return (IMultipleResults)(result.ReturnValue); } }
Assim para utilizarmos o método acima e executarmos a procedure o código seria assim:
// contexto NorthwindDataContext dataContext = new NorthwindDataContext(); // usando a interface IMultipleResults IMultipleResults results = dataContext.ListMultipleCustomersAndEmployees(); // result set Customers IEnumerable<Customer> customers = results.GetResult<Customer>(); // result set Employees IEnumerable<Employee> employees = results.GetResult<Employee>(); ...
O Visual Studio provavelmente não consegue fazer esse mapeamento corretamente porque podem existir stored procedures que dependendo de uma condição retornam entidades diferentes. A própria definição da interface IMultipleResults diz o seguinte:
Represents the results of mapped functions or queries with variable return sequences.
Espero que isso ajude vocês.
Links:
Northwind and pubs Sample Databases for SQL Server 2000
http://bit.ly/cWQNiL
IMultipleResults Interface
http://bit.ly/cFzS27
Stored Procedures (LINQ To SQL)
http://bit.ly/9wnZZg
Nenhum comentário:
Postar um comentário