@@ -29,6 +29,19 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
2929
3030 let cache = new MemoryCache( name = this.GetType() .Name)
3131 let methodsCache = new MemoryCache( name = this.GetType() .Name)
32+
33+ let splitKeyVal ( s : string ) =
34+ match s.Split( ':' ) with
35+ | [| key; value|] -> ( key.Trim() .ToLower(), value)
36+ |_ -> invalidArg " s" " parameter must be of type key:value"
37+
38+ let mapFromString ( s : string ) =
39+ match s with
40+ | " " -> Map.empty
41+ | x ->
42+ x.Split( '|' )
43+ |> Array.map splitKeyVal
44+ |> Map.ofArray
3245
3346 do
3447 this.Disposing.Add <| fun _ ->
@@ -44,10 +57,11 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
4457 ProvidedStaticParameter( " ConfigFile" , typeof< string>, " " )
4558 ProvidedStaticParameter( " DataDirectory" , typeof< string>, " " )
4659 ProvidedStaticParameter( " UseReturnValue" , typeof< bool>, false )
47- ProvidedStaticParameter( " ResultType" , typeof< ResultType>, ResultType.Records)
60+ ProvidedStaticParameter( " ResultType" , typeof< ResultType>, ResultType.Records)
61+ ProvidedStaticParameter( " ProcResultSets" , typeof< string>, " " )
4862 ],
4963 instantiationFunction = ( fun typeName args ->
50- let root = lazy this.CreateRootType( typeName, unbox args.[ 0 ], unbox args.[ 1 ], unbox args.[ 2 ], unbox args.[ 3 ], unbox args.[ 4 ])
64+ let root = lazy this.CreateRootType( typeName, unbox args.[ 0 ], unbox args.[ 1 ], unbox args.[ 2 ], unbox args.[ 3 ], unbox args.[ 4 ], unbox args .[ 5 ] |> mapFromString )
5165 cache.GetOrAdd( typeName, root)
5266 )
5367 )
@@ -59,6 +73,7 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
5973<param name='DataDirectory'>The name of the data directory that replaces |DataDirectory| in connection strings. The default value is the project or script directory.</param>
6074<param name='UseReturnValue'>To be documented.</param>
6175<param name='ResultType'>A value that defines structure of result: Records, Tuples, DataTable, or SqlDataReader, this affects only Stored Procedures.</param>
76+ <param name='ProcResultSets'>String defining a dictionary using the format key1:value1|key2:value2|...</param>
6277"""
6378
6479 this.AddNamespace( nameSpace, [ providerType ])
@@ -70,7 +85,7 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
7085 |> defaultArg
7186 <| base .ResolveAssembly args
7287
73- member internal this.CreateRootType ( typeName , connectionStringOrName , configFile , dataDirectory , useReturnValue , resultType ) =
88+ member internal this.CreateRootType ( typeName , connectionStringOrName , configFile , dataDirectory , useReturnValue , resultType , procResultSets ) =
7489 if String.IsNullOrWhiteSpace connectionStringOrName then invalidArg " ConnectionStringOrName" " Value is empty!"
7590
7691 let designTimeConnectionString = DesignTimeConnectionString.Parse( connectionStringOrName, config.ResolutionFolder, configFile)
@@ -124,7 +139,7 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
124139
125140 schemaType.AddMembersDelayed <| fun () ->
126141 [
127- let routines = this.Routines( conn, schemaType.Name, udttsPerSchema, resultType, designTimeConnectionString, useReturnValue, uomPerSchema)
142+ let routines = this.Routines( conn, schemaType.Name, udttsPerSchema, resultType, designTimeConnectionString, useReturnValue, uomPerSchema, procResultSets )
128143 routines |> List.iter tagProvidedType
129144 yield ! routines
130145
@@ -159,11 +174,16 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
159174 yield units
160175 ]
161176
162- member internal __.Routines ( conn , schema , uddtsPerSchema , resultType , designTimeConnectionString , useReturnValue , unitsOfMeasurePerSchema ) =
177+ member internal __.Routines ( conn , schema , uddtsPerSchema , resultType , designTimeConnectionString , useReturnValue , unitsOfMeasurePerSchema , procResultSets : Map < string , string > ) =
163178 [
164179 use _ = conn.UseLocally()
165180 let isSqlAzure = conn.IsSqlAzure
166181 let routines = conn.GetRoutines( schema, isSqlAzure)
182+
183+ let appendResultSet ( commandText : string ) =
184+ commandText + " " + defaultArg ( procResultSets.TryFind ( commandText.ToLower()) ) " "
185+
186+
167187 for routine in routines do
168188
169189 let cmdProvidedType = ProvidedTypeDefinition( snd routine.TwoPartName, Some typeof< `` ISqlCommand Implementation `` >, HideObjectMethods = true )
@@ -176,8 +196,15 @@ type SqlProgrammabilityProvider(config : TypeProviderConfig) as this =
176196 use __ = conn.UseLocally()
177197 let parameters = conn.GetParameters( routine, isSqlAzure, useReturnValue)
178198
199+ // there is a typo in function name `ToCommantText` should be Command instead of Commant
179200 let commandText = routine.ToCommantText( parameters)
180- let outputColumns = DesignTime.GetOutputColumns( conn, commandText, parameters, routine.IsStoredProc)
201+
202+ let commandTextWithResultSets =
203+ if not routine.IsStoredProc
204+ then commandText
205+ else commandText |> appendResultSet
206+
207+ let outputColumns = DesignTime.GetOutputColumns( conn, commandTextWithResultSets, parameters, routine.IsStoredProc)
181208 let rank = if routine.Type = ScalarValuedFunction then ResultRank.ScalarValue else ResultRank.Sequence
182209
183210 let hasOutputParameters = parameters |> List.exists ( fun x -> x.Direction.HasFlag( ParameterDirection.Output))
0 commit comments