F# Anonymous records support in query results
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
F# 4.6 added anonymous record support
These are similar to C# anonymous classes, but by design, the fields are sorted by name on creation so declaration order doesnt matter ( {| X=5; Y=6|} = {| Y=6; X=5 |} )
In dapper this create an issue when are used as a result type.
// dotnet add package Dapper
open System
open System.Data.SqlClient
open Dapper
// docker pull mcr.microsoft.com/mssql/server:2017-latest-ubuntu
// docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=<YourStrong!Passw0rd>" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2017-latest-ubuntu
let connection = @"Data Source=localhost,1433;Database=master;User=sa;Password=<YourStrong!Passw0rd>;";
use db = new SqlConnection(connection)
db.Open()
// OK, same order
let res = db.QuerySingle<{| Name: string; Tid: int; X:string; Y: int |}>("select Name='fdsf', Tid=20, X='hfds', Y=15")
// fails but understandable, different order
let res = db.QuerySingle<{| Name: string; Tid: int; X:string; Y: int |}>("select Tid=20, Name='fdsf', X='hfds', Y=15")
// fails and unexpected, same order
let res = db.QuerySingle<{| Tid: int; Name: string; X:string; Y: int |}>("select Tid=20, Name='fdsf', X='hfds', Y=15")
the error explain it doesnt find the constructor with right shape
Unhandled Exception: System.InvalidOperationException: A parameterless default constructor or one matching signature (System.Int32 Tid, System.String Name, System.String X, System.Int32 Y) is required for <>f__AnonymousType1611086028`4'[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] materialization
As note:
// F#
let x = {| Tid = 20; Name = "fdsf"; X = "hfds"; Y = 15 |}
// IL
IL_00ea: ldstr "fdsf"
IL_00ef: ldc.i4.s 20 // 0x14
IL_00f1: ldstr "hfds"
IL_00f6: ldc.i4.s 15 // 0x0f
IL_00f8: newobj instance void class '<>f__AnonymousType1611086028`4\''<string, int32, string, int32>::.ctor(!0/*string*/, !1/*int32*/, !2/*string*/, !3/*int32*/)
and
// C#
var x = new { Tid = 20, Name = "fdsf", X = "hfds", Y = 15 };
// IL
IL_0001: ldc.i4.s 20 // 0x14
IL_0003: ldstr "fdsf"
IL_0008: ldstr "hfds"
IL_000d: ldc.i4.s 15 // 0x0f
IL_000f: newobj instance void class '<>f__AnonymousType0`4'<int32, string, string, int32>::.ctor(!0/*int32*/, !1/*string*/, !2/*string*/, !3/*int32*/)```
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the supplied F# reproductions and compare their generated IL with the C# example; the report identifies constructor parameter ordering during Dapper materialization as the failing area. Done means the reordered F# anonymous-record queries materialize successfully without the constructor-shape exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, fsharp, sql
- Domain
- database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100