IfSharp icon indicating copy to clipboard operation
IfSharp copied to clipboard

dotnet core + npgsql entity framework core + paket loading issue

Open rudihorn opened this issue 5 years ago • 9 comments

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

rudihorn avatar Jun 26 '19 10:06 rudihorn

I've just fixed the related issue #232

However, if I switch to using #load "Paket.Generated.Refs.fsx" I get another issue:

image

If I load a dotnet fsi instance there's a similar issue with System.ComponentModel.Composition:

image

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.

cgravill avatar Jun 26 '19 11:06 cgravill

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.

rudihorn avatar Jun 26 '19 12:06 rudihorn

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

rudihorn avatar Jun 26 '19 12:06 rudihorn

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.

rudihorn avatar Jun 26 '19 12:06 rudihorn

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.

cgravill avatar Jun 26 '19 12:06 cgravill

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.

cgravill avatar Jun 26 '19 12:06 cgravill

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.

rudihorn avatar Jun 26 '19 13:06 rudihorn

@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?

rudihorn avatar Jun 26 '19 15:06 rudihorn

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?

cgravill avatar Jun 26 '19 15:06 cgravill