EF Core JET: AccessViolationException when 'updating' changed objects in MS Access

1

I'm building a .NET Core 3 console app with EF Core 2.2.x and EntityFrameworkCore.Jet to perform some generic reading and writing from/to an access database (mdb). I'm compiling for x86 as the docs say. Goal is to migrate lost and lots of data from a legacy system to a newer system (syncing data).

I've scaffolded the database, and I can perfectly read from the database, but as soon as I go and update an entity, I'm getting access violation exceptions:

Code sample (shortened for abbrevity):

public void SetSynced(int id)
{
    var item = _db.Products.Where(x => x.Id == id).Single();
    item.NeedsSyncing = false;
    _db.SaveChanges();
}

When this code is hit, the following Exception shows up (no innerexception)

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

I don't understand why this is happening as I can perfectly read the database, it does this only on writing.

I've tried using the following connection strings (drivers) but both with the same end-result:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\database.mdb;Jet OLEDB:Database Password = password;`
Provider=Microsoft.jet.oledb.4.0;Data Source=C:\\database.mdb;Jet OLEDB:Database Password = password;

When running on x64 reading works, but I'm getting the following exception:

System.Data.OleDb.OleDbException (0x80004002): No error message available, result code: E_NOINTERFACE(0x80004002).

I am lost and searching in the dark here. Does anyone have experience / ideas for me on where to look?

Update 02/02/2020: I've tried manually connecting using OleDb and running the query to see where that brings me. The below code works. When I switch it out with the above code it fails again.

db = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\database.mdb;Jet OLEDB:Database Password = password");
db.Open();
var command = new OleDbCommand($"UPDATE Products SET NeedsSyncing = 0 WHERE Id= 1", db);
var res = command.ExecuteNonQuery();

After setting up JetConfiguration.ShowSqlStatements = true I got the following stacktrace:

ExecuteDbDataReader==========
UPDATE [Products] SET [PictureName] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;


@p1(Int32) = 1
@p0(String) = 'notfound.jpg'
Fatal error. 0xC0000005
   at System.Data.Common.UnsafeNativeMethods+ICommandWithParameters.SetParameterInfo(IntPtr, IntPtr[], System.Data.OleDb.tagDBPARAMBINDINFO[])
   at System.Data.OleDb.OleDbCommand.ApplyParameterBindings(ICommandWithParameters, System.Data.OleDb.tagDBPARAMBINDINFO[])
   at System.Data.OleDb.OleDbCommand.CreateAccessor()
   at System.Data.OleDb.OleDbCommand.InitializeCommand(System.Data.CommandBehavior, Boolean)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(System.Data.CommandBehavior, System.Object ByRef)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(System.Data.CommandBehavior, System.String)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(System.Data.CommandBehavior)
   at System.Data.OleDb.OleDbCommand.ExecuteDbDataReader(System.Data.CommandBehavior)
   at System.Data.Common.DbCommand.ExecuteReader(System.Data.CommandBehavior)
   at System.Data.Jet.JetCommand.InternalExecuteDbDataReader(System.String, System.Data.CommandBehavior)
   at System.Data.Jet.JetCommand.ExecuteDbDataReader(System.Data.CommandBehavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(Microsoft.EntityFrameworkCore.Storage.IRelationalConnection, Microsoft.EntityFrameworkCore.Diagnostics.DbCommandMethod, System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.Object>)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(Microsoft.EntityFrameworkCore.Storage.IRelationalConnection, System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.Object>)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(Microsoft.EntityFrameworkCore.Storage.IRelationalConnection)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Microsoft.EntityFrameworkCore.DbContext, System.ValueTuple`2<System.Collections.Generic.IEnumerable`1<Microsoft.EntityFrameworkCore.Update.ModificationCommandBatch>,Microsoft.EntityFrameworkCore.Storage.IRelationalConnection>)
   at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[[System.ValueTuple`2[[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], 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.ValueTuple`2<System.__Canon,System.__Canon>, System.Func`3<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`2<System.__Canon,System.__Canon>,Int32>, System.Func`3<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`2<System.__Canon,System.__Canon>,Microsoft.EntityFrameworkCore.Storage.ExecutionResult`1<Int32>>)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(System.Collections.Generic.IEnumerable`1<Microsoft.EntityFrameworkCore.Update.ModificationCommandBatch>, Microsoft.EntityFrameworkCore.Storage.IRelationalConnection)
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(System.Collections.Generic.IReadOnlyList`1<Microsoft.EntityFrameworkCore.Update.IUpdateEntry>)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(System.Collections.Generic.IReadOnlyList`1<Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry>)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
   at Cashmaster.BackgroundWorker.Services.CashMasterService.Crash()

Nuget packages + versions (related to Jet):

Microsoft.EntityFrameworkCore 2.2.6
EntityFrameworkCore.Jet 2.2.0
System.Data.OleDb 4.7.0

Running this all on .NET Core 3.1.

ef-core-2.2
jet-ef-provider
asked on Stack Overflow Jan 31, 2020 by Erik J. • edited Feb 5, 2020 by Erik J.

1 Answer

0

The issue was tracked on GitHub by Migrate the x86 specific structures to AnyCPU for System.Data.OleDb #32509 and fixed with Fix x86 packing issues in System.Data.OleDb #33899 by a community member.

To fix the issue in your project, use the latest version of EF Core 3.1.x (currently 3.1.10) with the latest version of EntityFrameworkCore.Jet (currently prerelease 3.1.0-alpha.4) together with System.Data.OleDb release 5.0.0.

answered on Stack Overflow Dec 25, 2020 by lauxjpn

User contributions licensed under CC BY-SA 3.0