f# sqlite sqlprovider minBy maxBy 使用 float
f# sqlite sqlprovider minBy maxBy using float
我有一个 sqlite table,混合了整数和浮点列。我正在尝试获取每列的最大值和最小值。对于整数列,以下代码有效,但在浮点列上使用相同代码时出现转换错误:
let numCats = query{for row in db do minBy row.NumCats}
对于浮点列,我使用了以下代码,但速度很慢。
let CatHight = query{for row in db do select row.CatHeight} |> Seq.toArray |> Array.max
我有 8 个整数列和 9 个浮点列,所有列的行为都是一致的,所以我认为这是列类型的问题。但我是 F# 的新手,什么都不懂,所以我希望你能帮助我。
感谢您抽出宝贵时间提供帮助,非常感谢。
SQLProvider 版本:1.0.41
System.Data.SQLite.Core版本:1.0.104
错误是:System.InvalidCastException发生在FSharp.Core.dll
添加信息
我创建了一个新的 table,其中包含一列浮点类型。我插入了值 2.2 和 4.2。使用 SQLProvider 和 System.Data.SQLite.Core 我使用 minBy 或 maxBy 连接查询了数据库,我得到了转换异常。如果列类型是整数,它可以正常工作。
更多补充信息
异常详情:
System.Exception was unhandled
Message: An unhandled exception of type 'System.Exception' occurred in >FSharp.Core.dll
Additional information: Unsupported execution expression value(FSharp.Data.Sql.Runtime.QueryImplementation+SqlQueryable
1[FSharp.>Data.Sql.Common.SqlEntity]).Min(row => >Convert(Convert(row.GetColumn("X"))))`
失败的代码:
open FSharp.Data.Sql
[<Literal>]
let ConnectionString =
"Data Source=c:\MyDB.db;" +
"Version=3;foreign keys=true"
type Sql = SqlDataProvider<Common.DatabaseProviderTypes.SQLITE,
ConnectionString,
//ResolutionPath = resolutionPath,
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL>
let ctx = Sql.GetDataContext()
let Db = ctx.Main.Test
let x = query{for row in Db do minBy row.X}
printfn "x: %A" x
2017 年 2 月 1 日更新
另一个用户能够重现该问题,因此我向 SQLProvider 提交了一个问题。我现在正在寻找解决方法,虽然以下代码可以运行并且速度很快,但我知道有更好的方法来实现它——我只是找不到正确的方法。如果有人用更好的代码回答我会接受那个答案。再次感谢大家的帮助。
let x = query {for row in db do
sortBy row.Column
take 1
select row.Column } |> Seq.toArray |> Array.min
您需要将输出列强制为 int
或 float
(无论您需要还是给您带来麻烦)。您还需要注意,以防您的任何列都可以为空。下面的示例将首先将该列强制为 float
(以确保可为空),然后将其转换为 int
,最后获得最小值:
let x = query { for row in MYTABLE do
minBy (int (float row.MYCOLUMN))}
当然你可能想改变顺序,或者直接说 float Mycolumn
。
更新:
使用 Sqlite 它确实会导致错误。您可能想要执行 query { ... } |> Seq.minBy
来提取最小的数字。
这是我的解决方法,@s952163 和 SO f# 聊天室中的好人帮助了我。再次感谢所有提供帮助的人。
let x = query {for row in db do
sortBy row.Column
take 1
select row.Column } |> Seq.head
我有一个 sqlite table,混合了整数和浮点列。我正在尝试获取每列的最大值和最小值。对于整数列,以下代码有效,但在浮点列上使用相同代码时出现转换错误:
let numCats = query{for row in db do minBy row.NumCats}
对于浮点列,我使用了以下代码,但速度很慢。
let CatHight = query{for row in db do select row.CatHeight} |> Seq.toArray |> Array.max
我有 8 个整数列和 9 个浮点列,所有列的行为都是一致的,所以我认为这是列类型的问题。但我是 F# 的新手,什么都不懂,所以我希望你能帮助我。
感谢您抽出宝贵时间提供帮助,非常感谢。
SQLProvider 版本:1.0.41
System.Data.SQLite.Core版本:1.0.104
错误是:System.InvalidCastException发生在FSharp.Core.dll
添加信息
我创建了一个新的 table,其中包含一列浮点类型。我插入了值 2.2 和 4.2。使用 SQLProvider 和 System.Data.SQLite.Core 我使用 minBy 或 maxBy 连接查询了数据库,我得到了转换异常。如果列类型是整数,它可以正常工作。
更多补充信息
异常详情:
System.Exception was unhandled Message: An unhandled exception of type 'System.Exception' occurred in >FSharp.Core.dll Additional information: Unsupported execution expression
value(FSharp.Data.Sql.Runtime.QueryImplementation+SqlQueryable
1[FSharp.>Data.Sql.Common.SqlEntity]).Min(row => >Convert(Convert(row.GetColumn("X"))))`
失败的代码:
open FSharp.Data.Sql
[<Literal>]
let ConnectionString =
"Data Source=c:\MyDB.db;" +
"Version=3;foreign keys=true"
type Sql = SqlDataProvider<Common.DatabaseProviderTypes.SQLITE,
ConnectionString,
//ResolutionPath = resolutionPath,
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL>
let ctx = Sql.GetDataContext()
let Db = ctx.Main.Test
let x = query{for row in Db do minBy row.X}
printfn "x: %A" x
2017 年 2 月 1 日更新
另一个用户能够重现该问题,因此我向 SQLProvider 提交了一个问题。我现在正在寻找解决方法,虽然以下代码可以运行并且速度很快,但我知道有更好的方法来实现它——我只是找不到正确的方法。如果有人用更好的代码回答我会接受那个答案。再次感谢大家的帮助。
let x = query {for row in db do
sortBy row.Column
take 1
select row.Column } |> Seq.toArray |> Array.min
您需要将输出列强制为 int
或 float
(无论您需要还是给您带来麻烦)。您还需要注意,以防您的任何列都可以为空。下面的示例将首先将该列强制为 float
(以确保可为空),然后将其转换为 int
,最后获得最小值:
let x = query { for row in MYTABLE do
minBy (int (float row.MYCOLUMN))}
当然你可能想改变顺序,或者直接说 float Mycolumn
。
更新:
使用 Sqlite 它确实会导致错误。您可能想要执行 query { ... } |> Seq.minBy
来提取最小的数字。
这是我的解决方法,@s952163 和 SO f# 聊天室中的好人帮助了我。再次感谢所有提供帮助的人。
let x = query {for row in db do
sortBy row.Column
take 1
select row.Column } |> Seq.head