Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeLoad exception on .NET Framework 4.7.2 #612

Open
sliekens opened this issue Nov 13, 2024 · 2 comments
Open

TypeLoad exception on .NET Framework 4.7.2 #612

sliekens opened this issue Nov 13, 2024 · 2 comments

Comments

@sliekens
Copy link

sliekens commented Nov 13, 2024

Hi,

I'm having problems getting SQLitePCL to work in an older application which targets .NET Framework 4.7.2. Attempting to use SqliteConnection always throws System.TypeInitializationException from its constructor. The error seems to vary based on what bundle I use. Example error:

System.TypeInitializationException : The type initializer for 'Microsoft.Data.Sqlite.SqliteConnection' threw an exception.
---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
-------- System.Exception : Library e_sqlite3 not found
plat: win
suffix: DLL
possibilities (2):
    1) C:\Users\Steven\AppData\Local\Temp\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\assembly\dl3\40ea69d2\004c6898_94cbd801\runtimes\win-x64\native\e_sqlite3.dll
    2) C:\Users\Steven\AppData\Local\Temp\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\assembly\dl3\40ea69d2\004c6898_94cbd801\e_sqlite3.dll
win TryLoad: C:\Users\Steven\AppData\Local\Temp\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\assembly\dl3\40ea69d2\004c6898_94cbd801\runtimes\win-x64\native\e_sqlite3.dll
thrown: System.ComponentModel.Win32Exception (0x80004005): The specified module could not be found
   at SQLitePCL.NativeLibrary.TryLoad(String name, Loader plat, Action`1 log, IntPtr& h)
win TryLoad: C:\Users\Steven\AppData\Local\Temp\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\7fa9cc93-f4e3-4e7a-8908-50bcd00b20d6\assembly\dl3\40ea69d2\004c6898_94cbd801\e_sqlite3.dll
thrown: System.ComponentModel.Win32Exception (0x80004005): The specified module could not be found
   at SQLitePCL.NativeLibrary.TryLoad(String name, Loader plat, Action`1 log, IntPtr& h)
NOT FOUND

  Stack Trace:
     at Microsoft.Data.Sqlite.SqliteConnection..ctor(String connectionString)
   at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteRelationalConnection.CreateDbConnection()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated()
   at sqlitebug.UnitTest1.Create_database() in X:\src\sqlitebug\UnitTest1.cs:line 13
----- Inner Stack Trace -----
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Data.Sqlite.Utilities.BundleInitializer.Initialize()
   at Microsoft.Data.Sqlite.SqliteConnection..cctor()
----- Inner Stack Trace -----
   at SQLitePCL.NativeLibrary.Load(String libraryName, Assembly assy, Int32 flags)
   at SQLitePCL.Batteries_V2.MakeDynamic(String name, Int32 flags)
   at SQLitePCL.Batteries_V2.DoDynamic_cdecl(String name, Int32 flags)

Repro steps

Create sqlitebug.csproj with content:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.32" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
    <PackageReference Include="xunit" Version="2.5.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
  </ItemGroup>

</Project>

Create UnitTest1.cs with content:

using Microsoft.EntityFrameworkCore;
using Xunit;

namespace sqlitebug
{
    public class UnitTest1
    {
        [Fact]
        public void Create_database()
        {
            using (var context = new MyContext())
            {
                context.Database.EnsureCreated();
            }
        }
    }

    public class MyContext : DbContext
    {
        public DbSet<MyEntity> MyEntities { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=data.db");
        }
    }

    public class MyEntity
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Open a command prompt and run dotnet test.

Other info

What version of SQLitePCLRaw are you using?

bundle: SQLitePCLRaw.bundle_e_sqlite3
version: 2.1.2

(This is a transitive dependency of Microsoft.EntityFrameworkCore.Sqlite.)

What platform are you running on? What operating system? Which version? What CPU?

  • Windows 11
  • Intel 7700k (64-bit)

Are you using the command line, or an IDE? Which IDE? Which version of that IDE?

  • dotnet cli
  • VS2022

PS: I noticed the bundle uses a different provider for .NET Framework applications. Is that intended?
https://www.nuget.org/packages/SQLitePCLRaw.bundle_e_sqlite3/
image

@sliekens
Copy link
Author

If I change my setup to explicitly use the e_sqlite3 provider, the error changes.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <ItemGroup>
-    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.32" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.32" />
+    <PackageReference Include="SQLitePCLRaw.lib.e_sqlite3" Version="2.1.10" />
+    <PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" Version="2.1.10" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
    <PackageReference Include="xunit" Version="2.5.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
  </ItemGroup>

</Project>
        [Fact]
        public void Create_database()
        {
+            raw.SetProvider(new SQLite3Provider_e_sqlite3());
            using (var context = new MyContext())
            {
                context.Database.EnsureCreated();
            }
        }

Now the error is:

   System.DllNotFoundException : Unable to load DLL 'e_sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
  Stack Trace:
     at SQLitePCL.SQLite3Provider_e_sqlite3.NativeMethods.sqlite3_libversion_number()
   at SQLitePCL.raw.SetProvider(ISQLite3Provider imp)
   at sqlitebug.UnitTest1.Create_database() in X:\src\sqlitebug\UnitTest1.cs:line 12

I can see that e_sqlite3 does in fact exist in the output bin folder, in the platform-specific runtimes directories, but not in the root:

X:\SRC\SQLITEBUG\BIN
└───Debug
    └───net472
        │   Microsoft.Data.Sqlite.dll
        │   Microsoft.EntityFrameworkCore.dll
        │   Microsoft.EntityFrameworkCore.Relational.dll
        │   Microsoft.EntityFrameworkCore.Sqlite.dll
        │   sqlitebug.dll
        │   sqlitebug.dll.config
        │   sqlitebug.pdb
        │   SQLitePCLRaw.core.dll
        │   SQLitePCLRaw.provider.e_sqlite3.dll
        │
        └───runtimes
            ├───win-arm
            │   └───native
            │           e_sqlite3.dll
            │
            ├───win-x64
            │   └───native
            │           e_sqlite3.dll
            │
            └───win-x86
                └───native
                        e_sqlite3.dll

@sliekens
Copy link
Author

PPS: it works when I also specify the RID in my csproj, but I don't know why.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.32" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
    <PackageReference Include="SQLitePCLRaw.lib.e_sqlite3" Version="2.1.10" />
    <PackageReference Include="SQLitePCLRaw.provider.e_sqlite3" Version="2.1.10" />
    <PackageReference Include="xunit" Version="2.5.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
  </ItemGroup>

</Project>

So, this works, but at this point I have strong doubts if what I'm doing is within the intended usage patterns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant