F # FSharp.Data.SqlClient does not recognize multiple return tables from stored procedure

I'm not sure if this is possible, but I could not find clear documentation for this use case. I am using F # 4 and a library FSharp.Data.SqlClientto connect to Sql Server 2016. I want to call a stored procedure that returns multiple tables and turns these tables into corresponding records. In this case, the first table consists of items, and the second table consists of customers. My instinct is that it should look something like this:

let items, customers = cmd.Execute()

My gut is what itemswill be IEnumerable<item>, and customerswill be IEnumerable<customer>, where itemand customerare both types of recordings. However, it seems that it FSharp.Data.SqlClientsees only the first returned table from the stored procedure. I am working on an instance of SQL Server 2016 developer. Here is an example of T-SQL:

create table Item (
    ItemID int identity(1, 1) primary key,
    ItemName nvarchar(50)
)
go

create table Customer (
    CustomerID int identity(1, 1) primary key,
    CustomerName nvarchar(50)
)
go

insert into Item (ItemName) values ('A');
insert into Item (ItemName) values ('B');
insert into Item (ItemName) values ('C');

insert into Customer (CustomerName) values ('Gary');
insert into Customer (CustomerName) values ('Sergei');
insert into Customer (CustomerName) values ('Elise');
go

create procedure dbo.ExampleProcedure
as
begin
    set nocount on;

    select
        ItemID,
        ItemName
    from Item

    select
        CustomerID,
        CustomerName
    from Customer

end;

And here is the F # script I'm testing with. It shows what I would like to do, but I get a compilation error in the last line:

#r "../packages/FSharp.Data.SqlClient.1.8.2/lib/net40/FSharp.Data.SqlClient.dll"
#r "../packages/FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data

[<Literal>]
let connStr = 
    "Data Source=**connection string**;"

type queryExample = SqlProgrammabilityProvider<connStr>
do
    use cmd = new queryExample.dbo.ExampleProcedure(connStr)
    let items, customers = cmd.Execute()

I want to itemsmatch the first table returned and customersto match the second table returned. Intellisense assumes that FSharp.Data.SqlClient only sees the first table. When I hang over cmd.Execute(), the popup says "This expression was expected to have type 'a*'b but here has type System.Collections.Generic.IEnumerable<SqlProgrammabilityProvider<...>.dbo.ExampleProcedure.Record>". If I do the following, I access the request itemsin the stored procedure:

// Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project
// for more guidance on F# programming.
#r "../packages/FSharp.Data.SqlClient.1.8.2/lib/net40/FSharp.Data.SqlClient.dll"
#r "../packages/FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data

[<Literal>]
let connStr = 
    "Data Source=**connection string**;"

type queryExample = SqlProgrammabilityProvider<connStr>
do
    use cmd = new queryExample.dbo.ExampleProcedure(connStr)
    for item in cmd.Execute() do
        printfn "%A" item.ItemID

? ? , , , . ? .

2016-01-10: , , , #. # DataSet . . LINQ . :

using System.Data;
using System.Data.SqlClient;

var connStr = "**connection string**"
var sqlConnection = new SqlConnection(connStr );
var sqlCommand = new SqlCommand("ExampleProcedure", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
var dataSet = new DataSet();
var adapter = new SqlDataAdapter(sqlCommand);
adapter.Fill(dataSet);
var itemsTable = dataSet.Tables[0];
// Turn the itemsTable into a List<Item> using LINQ here
var customersTable = dataSet.Tables[1];
// Turn the customersTable into List<Customer> using LINQ here

, , , , , . , F # .

+4
1

F #, .

, , .

cmd.ExecuteReader() datareader, . , , "NextResult", ..

"NextResult": https://msdn.microsoft.com/pt-br/library/system.data.sqlclient.sqldatareader.nextresult(v=vs.110).aspx

0

Source: https://habr.com/ru/post/1666334/


All Articles