如何在 F# 中使用 Sqlprovider 映射可为空的 Guid 字段
How to Map Nullable Guid Field with Sqlprovider in F#
我遇到错误:
System.InvalidCastException: 'Unable to cast object of type 'System.Guid'
to type 'Microsoft.FSharp.Core.FSharpOption`1
使用此代码:
let products =
query {
for product in ctx.Dbo.Products do
select product
}
|> Seq.map(fun p -> p.MapTo<Product>())
|> Seq.toList
我已将我的类型缩小到几个字段以查看发生了什么
type Product = {
Id: Guid
SellDiscountCalcTypeId: Option<Guid>
Code: string
}
并且我的数据提供者设置正确(useOptionTypes = true)
type smBoomProvider =
SqlDataProvider<
DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER,
ConnectionString = smBoomConn,
IndividualsAmount = 1000,
UseOptionTypes = true
>
对于全为空的字段,没有错误,但一旦字段中有任何内容,它就会在运行时出错。
不幸的是,MapTo
方法似乎不支持 UseOptionTypes
标志。你可以解决这个问题,但它并不漂亮。一种方法是手动映射列:
let mapping (col : string, value : obj) =
match col with
| "SellDiscountCalcTypeId" ->
if isNull value then None
else Some (value :?> Guid)
:> obj
| _ -> value
let products =
query {
for product in ctx.Dbo.Products do
select product
}
|> Seq.map (fun p -> p.MapTo<Product>(mapping)) // use manual mapping
|> Seq.toList
另一个是显式 select 各个字段。这将尊重 UseOptionTypes
标志,至少:
module Product =
let create (id, sellDiscountCalcTypeId, code) =
{
Id = id
SellDiscountCalcTypeId = sellDiscountCalcTypeId
Code = code
}
let products =
query {
for product in ctx.Dbo.Products do
select (product.Id, product.SellDiscountCalcTypeId, product.Code) // explicitly select fields
}
|> Seq.map Product.create
|> Seq.toList
我遇到错误:
System.InvalidCastException: 'Unable to cast object of type 'System.Guid'
to type 'Microsoft.FSharp.Core.FSharpOption`1
使用此代码:
let products =
query {
for product in ctx.Dbo.Products do
select product
}
|> Seq.map(fun p -> p.MapTo<Product>())
|> Seq.toList
我已将我的类型缩小到几个字段以查看发生了什么
type Product = {
Id: Guid
SellDiscountCalcTypeId: Option<Guid>
Code: string
}
并且我的数据提供者设置正确(useOptionTypes = true)
type smBoomProvider =
SqlDataProvider<
DatabaseVendor = Common.DatabaseProviderTypes.MSSQLSERVER,
ConnectionString = smBoomConn,
IndividualsAmount = 1000,
UseOptionTypes = true
>
对于全为空的字段,没有错误,但一旦字段中有任何内容,它就会在运行时出错。
不幸的是,MapTo
方法似乎不支持 UseOptionTypes
标志。你可以解决这个问题,但它并不漂亮。一种方法是手动映射列:
let mapping (col : string, value : obj) =
match col with
| "SellDiscountCalcTypeId" ->
if isNull value then None
else Some (value :?> Guid)
:> obj
| _ -> value
let products =
query {
for product in ctx.Dbo.Products do
select product
}
|> Seq.map (fun p -> p.MapTo<Product>(mapping)) // use manual mapping
|> Seq.toList
另一个是显式 select 各个字段。这将尊重 UseOptionTypes
标志,至少:
module Product =
let create (id, sellDiscountCalcTypeId, code) =
{
Id = id
SellDiscountCalcTypeId = sellDiscountCalcTypeId
Code = code
}
let products =
query {
for product in ctx.Dbo.Products do
select (product.Id, product.SellDiscountCalcTypeId, product.Code) // explicitly select fields
}
|> Seq.map Product.create
|> Seq.toList