IfSharp
IfSharp copied to clipboard
dotnet core + npgsql entity framework core + paket loading issue
Description
Trying to load Npgsql entity framework on dotnet core over Paket has issues, most likely related to dependencies not being loaded.
Repro steps
#load "Paket.fsx"
Paket.Package ["Microsoft.EntityFrameworkCore"; "Npgsql"; "Npgsql.EntityFrameworkCore.PostgreSQL"]
#load ".paket/load/netstandard2.0/Npgsql.EntityFrameworkCore.PostgreSQL.fsx"
open Npgsql.EntityFrameworkCore.PostgreSQL
open Microsoft.EntityFrameworkCore
let opt = DbContextOptionsBuilder().UseNpgsql("connectionstring").Options
Expected behavior
It should generate a DbContextOptions
.
Actual behavior
type 'Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.NpgsqlDbContextOptionsBuilder' not found in assembly 'Npgsql.EntityFrameworkCore.PostgreSQL, Version=2.2.4.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version.
Known workarounds
I sadly could not find one. I've tried loading random further libraries, but with no success.
Related information
- Operating system: Ubuntu
- Branch: Master
- CoreCLR
I've just fixed the related issue #232
However, if I switch to using #load "Paket.Generated.Refs.fsx" I get another issue:
If I load a dotnet fsi instance there's a similar issue with System.ComponentModel.Composition:
So the next question is if that reference is essential, if not why Paket is generating a reference to it. Commenting it out doesn't help unfortunately either.
Could it be this reference is just stale? Have you tried running Paket.Clear ()
first?
With the latest patch I don't get the System.ComponentModel.Composition
error, and even if I force load it using Paket it does not solve the "not found in assembly" message.
Intellisense hints at:
A reference to the type 'System.Data.Common.DbConnection' in assembly 'netstandard' was found, but the type could not be found in that assembly
I've been wanting to also try debugging which libraries are loaded, but trying to access System.AppDomain.CurrentDomain
yields the error:
The value, namespace, type or module 'AppDomain' is not defined.
Good reminder on Paket.Clear() but no change there. It might be a operating system difference that you're not getting the error. Does your main.group.fsx
contain #r "System.ComponentModel.Composition"
?
I recommend trying to get this working via fsi plus the Paket load scripts. Given it doesn't work there for me, it's unlikely to work in the notebook. It's a lot easier to iterate there.
Btw if I make a new Visual Studio .NET Core project, add the Npgsql.EntityFrameworkCore.PostgreSQL NuGet then this does work there. So my guess it that this is somewhere between FSI and the load scripts Paket is creating.
Hmm let me double check this is not actually related to version incompatability.
Good reminder on Paket.Clear() but no change there. It might be a operating system difference that you're not getting the error. Does your
main.group.fsx
contain#r "System.ComponentModel.Composition"
?I recommend trying to get this working via fsi plus the Paket load scripts. Given it doesn't work there for me, it's unlikely to work in the notebook. It's a lot easier to iterate there.
My main.group.fsx
does not contain System.ComponentModel.Composition
. I can also confirm this does not work on fsi, but does work in a new project.
@cgravill so it seems that the issue is related due to lazy loading of libraries. Initially none of the libraries are in the current AppDomain, and simply using #r
does not do anything but tell the framework that they exist there. The libraries are only loaded when they are referenced, which is troublesome with what seems to be extension libraries. I am able to run the code I would like by running the following code segments in order:
#load "Paket.fsx"
Paket.Version ["Microsoft.EntityFrameworkCore.Design", "2.1.2"; "Npgsql", "4.0.3"; "Npgsql.EntityFrameworkCore.PostgreSQL", "2.1.2"]
#load "Paket.Generated.Refs.fsx"
This one forces the libraries to actually be loaded:
// reference assemblies
let failable f = try f () |> ignore with _ -> ()
failable (fun x -> Microsoft.Extensions.Logging.Abstractions.NullLoggerFactory())
failable (fun x -> Microsoft.Extensions.DependencyInjection.LoggingServiceCollectionExtensions.AddLogging(null))
failable (fun x -> Microsoft.EntityFrameworkCore.RelationalEntityTypeBuilderExtensions.HasDiscriminator(null))
failable (fun x -> Remotion.Linq.Parsing.ExpressionVisitors.MemberBindings.MethodInfoBinding.Bind(null, null))
failable (fun x -> Npgsql.TypeHandling.NpgsqlSafeReadException(null))
failable (fun x -> Microsoft.EntityFrameworkCore.DbFunctionAttribute())
open Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure
open Npgsql.EntityFrameworkCore.PostgreSQL
open Microsoft.EntityFrameworkCore
let opt = DbContextOptionsBuilder().UseNpgsql("connectionstring").Options
opt.GetType()
Do you have an idea where to best raise this?
Oh wow yes, that makes a sort of technical sense but seems horrible experience-wise.
Potentially this is a change in moving from .NET Framework to .NET Core? I tested in a .NET Framework notebook and didn't have an issue.
@cartermp any guidance on this?