Efcore: SaveChanges closes connection opened by user using EF API

Created on 8 Nov 2016  路  17Comments  路  Source: dotnet/efcore

I am using Sqlite in-memory for unit testing. I have upgraded from v1.0.1 to 1.1.0-preview1-final and I now get the error SQLite Error 1: 'no such table: xxx.

Steps to reproduce

  1. Run the code under SqlLite v1.0.1 and SqlServer v1.0.1 it works fine
  2. Upgrade to SqlLite 1.1.0-preview1-final and SqlServer 1.1.0-preview1-final and it fails with SQLite Error 1: 'no such table: xxx. on the unit test line:
db.BookAndAuthors.Count().ShouldEqual(4);
  1. Downgrade to v1.0.1 and it works again.

The SqlLite code is

        [Fact]
        public void TestWriteTestDataSqliteOk()
        {
            //SETUP
            var inMemDb = new SqliteInMemory();

            //ATTEMPT
            using (var db = inMemDb.GetContextWithSetup())
            {
                var books = EfTestData.CreateFourBooks();
                db.BookAndAuthors.AddRange(books);
                db.SaveChanges();

                //VERIFY
                db.BookAndAuthors.Count().ShouldEqual(4);
            }
        }

The SqliteInMemory class contains

public EfCoreContext GetContextWithSetup()
{
    var db = new EfCoreContext(InMemorySqlite());
    db.Database.OpenConnection();
    db.Database.EnsureCreated();

    var serviceProvider = db.GetInfrastructure();
    serviceProvider.GetService(typeof(ILoggerFactory));
    var loggerFactory = (ILoggerFactory)serviceProvider.GetService(typeof(ILoggerFactory));
    loggerFactory.AddProvider(new MyLoggerProvider(_logs));

    return db;
}

//---------------------------------------------------
//private methods

private DbContextOptions<EfCoreContext> InMemorySqlite()
{
    //Thanks to https://www.scottbrady91.com/Entity-Framework/Entity-Framework-Core-In-Memory-Testing
    var connectionStringBuilder =
        new SqliteConnectionStringBuilder { DataSource = ":memory:" };
    ConnectionString = connectionStringBuilder.ToString();
    var connection = new SqliteConnection(ConnectionString);

    // create in-memory db
    var builder = new DbContextOptionsBuilder<EfCoreContext>();
    builder.UseSqlite(connection);

    return builder.Options;
}

The issue

I get an exception SQLite Error 1: 'no such table: xxx. on the unit test line:

db.BookAndAuthors.Count().ShouldEqual(4);
Exception message: SQLite Error 1: 'no such table: BookAndAuthors'.
Stack trace:
at Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc, Sqlite3Handle db)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer)
   at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.GetResult[TResult](IEnumerable`1 valueBuffers)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass19_1`1.<CompileQuery>b__1(QueryContext qc)
   at test.UnitTests.TestEfTestData.TestWriteTestDataSqliteOk() in C:\Users\Jon\Documents\Visual Studio 2015\Projects\EfCoreInAction\test\UnitTests\TestEfTestData.cs:line 45

Further technical details

EF Core version: 1.1.0-preview1-final
Operating system: Windows 10
Visual Studio version: Microsoft Visual Studio Professional 2015
Version 14.0.25425.01 Update 3
Microsoft .NET Framework
Version 4.6.01586

Other details about my project setup: I have a DataLayer containing the classes and application DbContext. The tests are in a top-level test directory using XUnit

closed-fixed type-bug

All 17 comments

Possibly due to #6335--we might be looking for the database in a different location.

lol :memory: nevermind. 馃槃

In the wrong memory location?? 馃槅

Does it make a difference if you open the SqliteConnection before passing it to UseSqlite() (instead of calling DbContext.Database.OpenConnection() afterward)?

If so, it might be whatever the opposite of a connection leak is. (connection evaporation?)

Hi @bricelam,

Yes, opening

the SqliteConnection before passing it to UseSqlite() (instead of calling DbContext.Database.OpenConnection() afterward)?

fixed the problem, i.e.

var connection = new SqliteConnection(ConnectionString);
connection.Open();

... and removing the db.Database.OpenConnection(); worked a treat. Thanks for that. I will update my code to use that approach.

@bricelam Seems like this could be a breaking change?

Yes; re-opening. We need to understand why we're closing the connection in this case now.

SaveChanges() is closing connection in this case.

Hi,

I was expecting this bug to be fixed in release 1.1.1 but it doesn't seem to be fixed. Can you clarify:

  1. Is it fixed or not in version 1.1.1 of Microsoft.EntityFrameworkCore.Sqlite?
  2. If its fixed what is the proper way of opening the connection?

Thanks.

This bug is marked as fixed in the 2.0.0 release. You can try it out using the nightly builds

Removing milestone to reconsider for 1.1.2.

Discussed in triage and we are going to port this to 1.1.2, so it will ship with the next patch assuming this is approved.

@ajcvickers - Patch-proposed label?

This patch fix is approved. Please follow the normal code review / pull request process and make sure you make the change in the correct branch.

Preview builds of this patch fix should be available on the following feeds:

If you have a chance, please try out these preview builds and let us know if you have any feedback!

I have recently encountered the same problem after upgrading to V 2.0 and all my integration tests are now marked failed !!
Could anyone guide me to a solution?!

@AhmedElbatt This issue was fixed before 2.0, so the behavior you are seeing may be due to a different reason. Please file a new issue including a full code listing or project that reproduces what you are seeing.

Was this page helpful?
0 / 5 - 0 ratings