根据先前的类型选择生成F#类型

时间:2018-10-28 11:12:22

标签: f# type-providers f#-data fsharp.data.typeproviders

尝试根据先前类型提供的参数生成新类型。

这是尝试的代码snippet

据我了解,dimensionsType应该从here传递一个参数agencyId,稍后我会在生成新的ProvidedProperty之前使用它来filter的值。

出于某种原因,dimensionsType中的agencyId值正确,但AddMembersDelayed中的匿名function值却不相同,取而代之的是collectionType:{{ 1}}参数。

dimensionsType "WB"

Usage.fsx

connection.Dataflows=> [
    // Id    Name                          AgencyId
    ("SDG", "SDG",                         "UNSD"),
    ("WDI", "World Development Indicators", "WB")
]


connection.Dimensions=> [
    //Id   AdgencyId
    ("WB", "FREQ"),
    ("WB", "SERIES"),
    ("WB", "REF_AREA"),
    ("UNSD", "FREQ111")
]




let dimensionsType agencyId =
    printfn "dimensionsType arg: [%s]" agencyId
    let someIntVal = 42            
    let someStrVal = "Str"            
    let t = ProvidedTypeDefinition("Dimensions", Some typeof<Dimensions>, hideObjectMethods = true, nonNullable = true)
    let fsn = fun aid () -> 
        [ for dimension in connection.Dimensions do
              printfn "dimension.agencyId [%s] - [%s] - [%s] - [%d] - [%s]" dimension.Id dimension.AgencyId aid someIntVal someStrVal
              if dimension.AgencyId = aid then
                  let prop = 
                      ProvidedProperty
                        ( dimension.Id, dimensionType, 
                          getterCode = (fun (Singleton arg) -> <@@ ((%%arg : Dimensions) :> IDimensions).GetDimension(dimension.EnumerationId) @@>))
                  if not (String.IsNullOrEmpty dimension.Position) then prop.AddXmlDoc(dimension.Position)
                  yield prop                     
        ]
    t.AddMembersDelayed (fsn agencyId)
    serviceTypesType.AddMember t
    t

let dataflowsType =
    let dataflowCollectionType = ProvidedTypeBuilder.MakeGenericType(typedefof<DataflowCollection<_>>, [ dimensionsType "WB"])
    let t = ProvidedTypeDefinition("Dataflows", Some dataflowCollectionType, hideObjectMethods = true, nonNullable = true)
    t.AddMembersDelayed (fun () ->
        [ for dataflow in connection.Dataflows do
            let prop =
                ProvidedProperty
                  ( dataflow.Name, dimensionsType dataflow.AgencyID,
                    getterCode = (fun (Singleton arg) -> <@@ ((%%arg : DataflowCollection<Dataflow>) :> IDataflowCollection).GetDataflow(dataflow.Id, dataflow.Name) @@>))
            prop.AddXmlDoc (sprintf "The data for dataflow '%s'" dataflow.Name)                
            yield prop])
    serviceTypesType.AddMember t
    t

我要实现的结果是针对以下两种情况生成了不同的属性:

#r @"../../../bin/lib/net45/FSharp.Data.dll"

open FSharp.Data
type SD = SdmxDataProvider<"https://api.worldbank.org/v2/sdmx/rest">
let wb = SD.GetDataContext()
let dataflows = wb.Dataflows // Output below is result of this line execution

F#交互式输出

wb.Dataflows.``World Development Indicators``. // based on ``World Development Indicators`` agencyId
wb.Dataflows.SDG // based on SDG agencyId

0 个答案:

没有答案