0

I'm using microsoft.data.sqlclient library. I’m trying to execute this simple code in F# interactive:

#r @"C:\Users\micha\.nuget\packages\microsoft.data.sqlclient\5.1.0\ref\net6.0\Microsoft.Data.SqlClient.dll"

open Microsoft.Data.SqlClient

let conn = new SqlConnection("CONN_STR")
conn.Open()
let state = conn.State

Everything blowns up at the last step:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Data.SqlClient.SqlConnection.get_State() in D:\a\_work\1\s\src\Microsoft.Data.SqlClient\netcore\ref\Microsoft.Data.SqlClient.cs:line 889
   at <StartupCode$FSI_0006>.$FSI_0006.main@() in C:\some\path\stdin:line 3
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Stopped due to error

Everything is working if I just execute the same code as normal console app

Why I'm getting this error when I'm doing that in F# interactive?

2 Answers2

2

I stop getting exceptions after making two changes:

Reference the package like this:

#r "nuget: Microsoft.Data.SqlClient"

Switch FSI to use .Net Core (Tools|Options|F# Tools|F# Interactive -> set "Use .NET Core Scripting" to True)

I have no idea why.

Jim Foye
  • 1,918
  • 1
  • 13
  • 15
  • many thanks, your way of referencing works for me. I'm not able to do the second option because I'm using Rider but that is fine. I'm not going to mark your solution as correct for a while because I want to hear the reason why my way of importing is not working. Moreover doing importing with `nuget...` is a little bit more time-consuming which is not importnat for now but could be important in a future – Michael Samoilenko Aug 29 '23 at 06:46
  • There are similar options in Rider for F# Interactive. I have Rider installed, but I only tried this in Visual Studio. I agree it would be great if someone gave us a fuller explanation. – Jim Foye Aug 29 '23 at 15:34
2

As @Jim Foye pointed out, the best way to go is to reference the package with #r "nuget:".

As for why your original code throws an exception: the assemblies in the ref folder of a package, when there is one, are so-called "reference assemblies". They contain all the same classes and methods as the corresponding runtime assemblies except with invalid implementations, and they are only meant to be used during compilation, not at runtime. The assemblies that are actually used at runtime are in the lib folder.

Tarmil
  • 11,177
  • 30
  • 35
  • ah, I see thanks! – Michael Samoilenko Aug 30 '23 at 09:18
  • @MichaelSamoilenko To be more precise: if method doesn't have return value (returns `void`) then body is empty. If method should return something, then body is `throw null`. Throwing `null` value results in `NullReferenceException`. It seems to be the reason why you get NRE. Dotnet team decided that reference assemblies must be correct from point of runtime, though getting `InvalidProgramException` or something more specialized would be more helpful in this situation – JL0PD Sep 01 '23 at 07:02