标签: f#-data

JsonProvider 可以反序列化为 Generic.Dictionary 吗?

我正在学习类型提供程序,它看起来像是一个突破性的功能。但是,我无法设法使用 JsonProvider 反序列化 json,以便目标类型具有 Generic.Dictionary 属性。可以使用 Json.NET 来完成。这是代码:

type ByProv = JsonProvider<"""{"dict":{"A":1,"B":2}}""">
type ByHand(d:Dictionary<string,int>) =
    member val dict = d with get,set

let text = """{"dict":{"C":3,"D":4}}"""
let newt = JsonConvert.DeserializeObject<ByHand> text
let prov = ByProv.Parse text
printfn "%A" newt.dict.["C"]
//Can only call statically inferred A or B (and it will throw at run-time)
printfn "%A" prov.Dict.A
Run Code Online (Sandbox Code Playgroud)

显然,dict被推断为记录类型,而不是Dictionary默认类型。这可以被覆盖吗?

f# type-providers f#-data

5
推荐指数
1
解决办法
546
查看次数

FSharp.Data - 如何处理空JSON值?

我正在尝试将FSharp.Data示例转换为我正在处理的问题的解决方案,但我只是没有走得太远.

问题

给定返回json的端点类似于:

{
  Products:[{
    Id:43,
    Name:"hi"
  },
  {
    Id:45,
    Name:"other prod"
  }
  ]
}
Run Code Online (Sandbox Code Playgroud)

如何加载数据然后只Id从实际的现有数据中获取数据?

我不明白如何"模式匹配"的可能性:

  • 它什么都不会回报
  • root.Products可能是不存在/空
  • Id可能不存在

通过Null匹配尝试

namespace Printio

open System 
open FSharp.Data
open FSharp.Data.JsonExtensions

module PrintioApi =
    type ApiProducts = JsonProvider<"https://api.print.io/api/v/1/source/widget/products?recipeId=f255af6f-9614-4fe2-aa8b-1b77b936d9d6&countryCode=US">

let getProductIds url =
    async {
        let! json = ApiProducts.AsyncLoad url
        let ids = match json with
            | null  -> [||]
            | _ -> 
                match json.Products with
                    | null -> [||]
                    | _ -> Array.map (fun (x:ApiProducts.Product)-> x.Id) …
Run Code Online (Sandbox Code Playgroud)

f# json f#-data

5
推荐指数
2
解决办法
1092
查看次数

使用JSONProvider重用类型定义?

我正在使用FSharp-Data中的JSONProvider自动为我正在使用服务的示例响应消费的Web服务创建类型.

但是,当涉及到在服务中重用的类型时,我有点困惑,例如,有一个api方法返回X类型的单个项,而另一个返回X列表,依此类推.我真的必须为此生成多个定义,并不意味着我会为同一个东西重复类型吗?

所以,我想我真正想问的是,有没有办法从JSON样本生成的类型中创建复合类型?

f# json type-providers f#-data

5
推荐指数
1
解决办法
187
查看次数

为什么在创建 SqlClient 类型时会出现缺少的方法异常运行时?

我有以下代码:

open FSharp.Data

[<Literal>]
let connectionString = @"Data Source=(local)\SQLExpress;Integrated Security=SSPI;Database=SfagStage"

type InsertEnhet = SqlCommandProvider<"Sql\InsertEnhet.sql", connectionString>

let insertEnhet (enhet:Enhet) = 
    let cmd = new InsertEnhet() // <<--- This generates an error runtime
    cmd.Execute(enhet.Navn, enhet.Enhetsnummer, enhet.LEIKode, enhet.Kommune, DateTime.Now)
Run Code Online (Sandbox Code Playgroud)

我创建命令的行是导致我认为缺少方法的原因。我认为重要的例外部分是:

System.MissingMethodException: Method not found: 'Void FSharp.Data.ISqlCommand Implementation..ctor(FSharp.Data.Connection, Int32, System.String, Boolean, System.Data.SqlClient.SqlParameter[], FSharp.Data.ResultType, FSharp.Data.ResultRank, Microsoft.FSharp.Core.FSharpFunc`2, System.String)'.
Run Code Online (Sandbox Code Playgroud)

f# type-providers f#-data assembly-binding-redirect fsharp.sqlclient

5
推荐指数
1
解决办法
929
查看次数

混合类型的F#集合类型

这个问题来自于正在努力从R转换到F#的人.我完全承认我的方法可能是错的,所以我正在寻找F#这样做的方法.我有一种情况,我想迭代一组XML文件,解析它们,并提取几个值,以确定哪些需要进一步处理.我的自然倾向是映射XML数据数组,exampleData在这种情况下,使用RawDataProvider类型提供程序解析每个数据,最后为包含解析的XML,XML中的Status值和ItemId值的每个文件创建一个Map对象.

事实证明,F#中的Map类型与R中的List不同.R中的列表本质上是可以支持混合类型的哈希映射.看来F#中的Map类型不支持存储混合类型.我发现这在我的R工作中非常有用,我正在寻找合适的F#系列.

或者,我是否认为这一切都错了?这是我在R中处理数据的一种非常自然的方式,所以我希望有一种方法可以在F#中进行处理.假设我将进行进一步分析并向这些集合添加其他数据元素.

更新: 这似乎是一个简单的用例,必须有一种惯用的方式在F#中执行此操作,而无需为每个分析步骤定义记录类型.我已经更新了我的例子,以进一步说明我想要做的事情.我想返回我分析的Map对象数组:

type RawDataProvider = XmlProvider<"""<product Status="Good" ItemId="123" />""">        

let exampleData = [| """<product Status="Good" ItemId="123" />"""; """<product Status="Bad" ItemId="456" />"""; """<product Status="Good" ItemId="789" />"""|]

let dataResult =
            exampleData
            |> Array.map(fun fileData -> RawDataProvider.Parse(fileData))
            |> Array.map(fun xml -> Map.empty.Add("xml", xml).Add("Status", xml.Status).Add("ItemId", xml.ItemId))
            |> Array.map(fun elem -> elem.["calc1Value"] = calc1 elem["itemId"])
            |> Array.map(fun elem -> elem.["calc2"] = calc2 elem.["ItemId"] elem.["calc1Value"])
Run Code Online (Sandbox Code Playgroud)

f# dictionary f#-data

5
推荐指数
1
解决办法
521
查看次数

FSharp.Data HTTP 请求 - 无法设置请求超时

我们有一个简单的 F# 控制台应用程序,它通过FSharp.Data Http.Request. 我们正在使用该customizeHttpRequest参数来尝试设置请求超时属性。我们的用法如下:

let response = Http.Request(
    serviceEndpoint,
    headers = requestHeaders,
    body = requestBody,
    silentHttpErrors = true,
    customizeHttpRequest = (fun request -> request.Timeout <- 1000; request))
Run Code Online (Sandbox Code Playgroud)

我们观察到我们的自定义超时被忽略(即请求在 1 秒后不会超时,如本例所示)。System.Net.HttpWebRequest我们还观察到,在默认超时 100,000ms后,请求不会超时。

这里有问题吗,还是我们没有customizeHttpRequest正确使用参数?

f# f#-data

5
推荐指数
1
解决办法
534
查看次数

F# HTML 提供程序按列迭代表

有没有办法按表的列而不是按行进行迭代?API示例在行中有结算日期信息:

Settlement Day,Period,IMBALNGC,Offer Volume Bid Volume,Accepted Offer Vol,Accepted Bid Vol,UAOV,UABV,PAOV,PABV
2014-01-14,1,877.000,52378.500,-53779.500,348.200,-654.374,0.000,0.000,348.200,-654.374 
2014-01-14,2,196.000,52598.000,-53559.500,349.601,-310.862,0.000,0.000,316.701,-310.862 
2014-01-14,3,-190.000,52575.000,-53283.500,186.183,-2.426,0.000,0.000,162.767,-1.917 
2014-01-14,4,-61.000,52576.000,-53454.500,18.000,-24.158,0.000,0.000,18.000,-24.158 
Run Code Online (Sandbox Code Playgroud)

但是,如果结算日信息在列中,有没有一种方法可以执行类似于 API 示例的操作,如下所示:

let firstCol = mrktDepth.Columns|> Seq.head
let settlementDate = firstCol.``Settlement Day``
let acceptedBid = firstCol.``Accepted Bid Vol``
let acceptedOffer = firstCol.``Accepted Offer Vol``
Run Code Online (Sandbox Code Playgroud)

f# f#-data

5
推荐指数
0
解决办法
141
查看次数

F#数据类型+ SQL-Server持久性(使用No-SQL技术)

我的F#应用程序具有非常好的F#模型,充分利用了F#类型系统(联合,记录,元组和基元类型).我试图找出将这些数据类型保存到SQL-Server数据库的最佳方法.

让我们做出以下假设:

  • 我想要持久化的中心实体是一个被称为的判别联盟,Task它有大约30个不同的联合案例,每个案例具有完全不同的属性(可能是其他的DU,记录或元组或原始类型),这使得使用矩形关系表格实施起来非常繁琐

  • 我希望每周多次不断改进这些模型,CI会在提交后立即将我的应用程序部署到生产中.同样,使用常规表会使ALTER TABLE语句减慢我的开发和部署速度,并且会增加大量的认知过载,任何新开发人员都会在这个系统上遇到挑战

  • 在进行模型演变后,我应该能够轻松地使用后台进程在线升级我的旧模型,或者从数据库中获取时,使用接近0的停机时间

  • 我应该能够在任意深度查询这些模型,并且我已经接近一百万行来处理,并且这将继续增长.查询速度应该很快,最多为100毫秒

  • 我需要使用SQL Server,因为此应用程序是较大系统的一小部分,我希望任何数据库操作都参与任何正在进行的数据库事务


序列化为TaskJSON

这是我的第一次尝试 - 将所有内容存储为JSON,识别可查询值,使用SQL Server 2016的新JSON函数将它们存储在索引表中.SQL Server中的JSON函数非常快,但索引这些查询要求我使用持久+计算+索引列或索引视图.

烦恼:

  • 非常难以进化模型,特别是如果我想要进化所有类型X的实例,这些实例可能出现在不同联合情况的不同深度.没有标准化的语言可以指出这些演变

  • JSON不区分十进制/浮点数/数字,这有时很难处理,我需要自定义格式化程序.小问题,没什么大不了的.

  • 查询语言在任意深度都有些原始,并且这些查询没有索引,因此新查询几乎总是要求我创建计算列或更改索引视图.

  • 将新的索引列添加到索引视图不是ONLINE操作并导致停机,并且很难在CI中自动化

  • 在同一个表中使用PERSISTED COLUMNS有时会导致SQL Server在搜索/选择时没有真正使用它们,而是从头开始重新计算这些值(因为它在查询计划器中没有准确地计算出这个操作的成本)


序列化为TaskXML

这是我目前的实施.

  • 我编写了自己的自定义XML序列化程序,这使我很容易使用XQuery和SQL Server的xml数据类型列查询数据库

  • 使用功能非常强大的XSLT,模型演变变得轻而易举

问题:

  • 即使添加了所有可能的XML索引,查询也很慢 - 大约需要5秒钟(在Azure P6 SQL实例中)
  • 对于不同的持久模型版本,只需略微不同的查询,这会使它更加昂贵
  • 非索引的XML函数非常慢,并且需要永远构建索引表/持久列,所以我不能真正使用它.

我对我的XML解决方案非常满意 - 我只需要一种方法来加快我的XML查询,我想在这一点上,我已经达到了SQL Server可以提供的极限.

还有其他方法我错过了F#社区试图能够持久保存非常丰富的F#数据模型吗?

f# xml-database f#-data

5
推荐指数
0
解决办法
206
查看次数

使用 FSharp.Data 有什么方法可以将 JsonValue 转换为 JsonProvider 类型?

我知道我可以通过序列化到一个字符串并返回到 json 提供程序类型。我更喜欢更清洁的解决方案。用户获得 JsonValue 并且可能希望使用使用 JsonProvider 的类型化版本是一个小型 http 框架。

就像是:

type Balance = JsonProvider<"""{"balance":100}""">

let value = JsonValue.parse<"""{"balance":100}""">

let typed = Balance.fromValue value
Run Code Online (Sandbox Code Playgroud)

f# f#-data

5
推荐指数
0
解决办法
313
查看次数

F# 类型提供程序在引用项目中查找示例文件,而不是引用的项目

我有一个库,我使用FSharp.Data'sJsonProvider从 JSON 文件构造类型。但是,当我在控制台应用程序中引用该项目并尝试访问生成的类型时,它不会编译,而是在控制台应用程序的目录中查找示例文件,产生如下错误

Cannot read sample JSON from 'sample.json': Could not find file 'C:\Some\Where\TheSolution\ConsoleApp\sample.json
Run Code Online (Sandbox Code Playgroud)

我真的必须将示例文件复制到每个引用项目中,还是必须将其添加为 DLL 才能使其正常工作,还是我做错了什么?

f# f#-data

5
推荐指数
1
解决办法
217
查看次数