Skip to content

Commit 7239c7f

Browse files
committed
* ValueNone via reflection is simplified
* Added tests
1 parent db5419d commit 7239c7f

2 files changed

Lines changed: 37 additions & 16 deletions

File tree

src/SQLProvider.Common/SqlRuntime.Common.fs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ open FSharp.Data.Sql.Transactions
1414
open FSharp.Data.Sql.Schema
1515
open Microsoft.FSharp.Reflection
1616
open System.Collections.Concurrent
17+
open System.Runtime.Serialization
1718

1819
type DatabaseProviderTypes =
1920
| MSSQLSERVER = 0
@@ -361,9 +362,8 @@ type SqlEntity(dc: ISqlDataContext, tableName, columns: ColumnLookup, activeColu
361362
[|
362363
for prop in fields do
363364
match dataMap.TryGetValue(clean prop) with
364-
| true, null when (prop.PropertyType.Name.StartsWith "FSharpValueOption" || prop.PropertyType.Name.StartsWith "FSharpOption") ->
365-
let cases = FSharpType.GetUnionCases prop.PropertyType
366-
let typedNone = FSharpValue.MakeUnion(cases[0], null)
365+
| true, null when prop.PropertyType.Name.StartsWith "FSharpValueOption" ->
366+
let typedNone = FormatterServices.GetUninitializedObject prop.PropertyType
367367
yield propertyTypeMapping (prop.Name, typedNone)
368368
| true, dataVal -> yield propertyTypeMapping (prop.Name, (Utilities.convertTypes dataVal prop.PropertyType))
369369
| false, _ -> ()
@@ -373,9 +373,8 @@ type SqlEntity(dc: ISqlDataContext, tableName, columns: ColumnLookup, activeColu
373373
let instance = Activator.CreateInstance<'a>()
374374
for prop in typ.GetProperties() do
375375
match dataMap.TryGetValue(clean prop) with
376-
| true, null when (prop.PropertyType.Name.StartsWith "FSharpValueOption" || prop.PropertyType.Name.StartsWith "FSharpOption") ->
377-
let cases = FSharpType.GetUnionCases prop.PropertyType
378-
let typedNone = FSharpValue.MakeUnion(cases[0], null)
376+
| true, null when prop.PropertyType.Name.StartsWith "FSharpValueOption" ->
377+
let typedNone = FormatterServices.GetUninitializedObject prop.PropertyType
379378
prop.GetSetMethod().Invoke(instance, [|propertyTypeMapping (prop.Name, typedNone)|]) |> ignore
380379
| true, dataVal -> prop.GetSetMethod().Invoke(instance, [|propertyTypeMapping (prop.Name, (Utilities.convertTypes dataVal prop.PropertyType))|]) |> ignore
381380
| false, _ -> ()

tests/SqlProvider.Tests/QueryTests.fs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,26 +2931,48 @@ let ``mock for unit-testing: datacontext``() =
29312931

29322932

29332933
// Generated with dc.Main.OrderDetails.TemplateAsRecord
2934-
type MyMainOrders = { CustomerId : String voption; EmployeeId : Int64 voption; Freight : Decimal voption; OrderDate : DateTime voption; OrderId : Int64; RequiredDate : DateTime voption; ShipAddress : String voption; ShipCity : String voption; ShipCountry : String voption; ShipName : String voption; ShipPostalCode : String voption; ShipRegion : String voption; ShippedDate : DateTime voption }
2935-
2936-
type MyMainOrders2() =
2937-
class
2938-
member val CustomerId = ValueSome "" with get,set
2939-
member val ShipRegion = ValueSome "" with get,set
2940-
end
2934+
type OrderDetailsRecordVopts = { CustomerId : String voption; EmployeeId : Int64 voption; Freight : Decimal voption; OrderDate : DateTime voption; OrderId : Int64; RequiredDate : DateTime voption; ShipAddress : String voption; ShipCity : String voption; ShipCountry : String voption; ShipName : String voption; ShipPostalCode : String voption; ShipRegion : String voption; ShippedDate : DateTime voption }
29412935

2936+
type OrderDetailsClassVopts() =
2937+
member val CustomerId = ValueSome "" with get, set
2938+
member val ShipRegion = ValueSome "" with get, set
29422939

29432940
[<Test >]
2944-
let ``simple select query with MapTo``() =
2941+
let ``simple select query with MapTo with voptions``() =
29452942
let dc = sqlValueOption.GetDataContext()
29462943

29472944
let qry =
29482945
query {
29492946
for ord in dc.Main.Orders do
29502947
select (ord)
29512948
} |> Seq.head
2952-
let mapped1 = qry.MapTo<MyMainOrders>()
2953-
let mapped2 = qry.MapTo<MyMainOrders2>()
2949+
let mapped1 = qry.MapTo<OrderDetailsRecordVopts>()
2950+
let mapped2 = qry.MapTo<OrderDetailsClassVopts>()
29542951

29552952
Assert.AreEqual(ValueSome "VINET", mapped1.CustomerId)
2953+
Assert.True(mapped1.ShipRegion.IsNone)
29562954
Assert.AreEqual(ValueSome "VINET", mapped2.CustomerId)
2955+
Assert.True(mapped2.ShipRegion.IsNone)
2956+
2957+
type OrderDetailsRecordOpts = { CustomerId : String option; EmployeeId : Int64 option; Freight : Decimal option; OrderDate : DateTime option; OrderId : Int64; RequiredDate : DateTime option; ShipAddress : String voption; ShipCity : String option; ShipCountry : String option; ShipName : String option; ShipPostalCode : String option; ShipRegion : String option; ShippedDate : DateTime option }
2958+
2959+
type OrderDetailsClassOpts() =
2960+
member val CustomerId = Some "" with get, set
2961+
member val ShipRegion = Some "" with get, set
2962+
2963+
[<Test >]
2964+
let ``simple select query with MapTo with options``() =
2965+
let dc = sqlOption.GetDataContext()
2966+
2967+
let qry =
2968+
query {
2969+
for ord in dc.Main.Orders do
2970+
select (ord)
2971+
} |> Seq.head
2972+
let mapped1 = qry.MapTo<OrderDetailsRecordOpts>()
2973+
let mapped2 = qry.MapTo<OrderDetailsClassOpts>()
2974+
2975+
Assert.AreEqual(Some "VINET", mapped1.CustomerId)
2976+
Assert.True(mapped1.ShipRegion.IsNone)
2977+
Assert.AreEqual(Some "VINET", mapped2.CustomerId)
2978+
Assert.True(mapped2.ShipRegion.IsNone)

0 commit comments

Comments
 (0)