EntityFramework deletes my entries on dbcontext creation

In a .NET Core project, I have the following model:

public class WrapperContext : DbContext
{
    public DbSet<WrappedFunction> Functions { get; set; }

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

public class WrappedFunction
{
    [Key]
    public int FunctionId { get; set; }
    public String FunctionName { get; set; }
    public String AssemblyPath { get; set; }
    public String FactoryName { get; set; }
}

      

As you can see, this is a Sqlite database.

I added an initial migration and updated the database. Before running my test application, I filled the Functions table with one entry. I can open the DB using the SqliteManager to see the entry.

Then I try to access the DB with the following function:

    static MUinfo getInfoFor(String command)
    {
        UFInfo rv = null;

        using (var ctx = new WrapperContext())  // <---- record disappears here
        {
            foreach (var fn in ctx.Functions)
            {
                if (fn.FunctionName.Equals(command))
                {
                    rv = new UFInfo()
                    {
                        AssemblyPath = fn.AssemblyPath,
                        FactoryName = fn.FactoryName,
                        CommandName = command
                    };
                }
            }
        }

        if (rv != null) return rv;
        return "No Info for " + command;
    }

      

However, when going through the debugger, I see that the loop foreach

never runs as there are no entries in the database. When I stop before executing foreach

, I can verify (using the SqliteManager) that my only record has been deleted from the database.

So it looks like the DbContext object is deleting data from the database in some way. Why would that be and what have I done wrong here? I'm new to EntityFramework, so I might have done something obvious, but it's not obvious to me.

One more bit of information here. The project accessing the db is a library project. I have to copy the DB to the app's build directory before I can populate it and run the app. I don't know if it matters or not.

Edit 6/19/17 (18:51):

OK. A bit more info (thanks to @StevePy). Nunit3 seems to be in conflict with EFCore (although I don't get any errors when restoring), so I couldn't create a unit test for that. So I pasted using (var ctx...)

higher than the above list and inserted a couple of dummy records. Then I walked out of that block, and when I entered the one to cross the records, they were there.

However, I then commented out the dummy inserts and repeated my test. Once again, both entries disappeared. So, there is something very strange with EFCore here.

Edit 6/20/17 (15:30): Well I'm still not sure what's going on, but there is an odd interaction between EFCore and Microsoft.Data.Sqlite.

I decided to remove all references to EFCore and just use SQL queries in the DB. I did it without recreating the DB (so I used the one already created by EFCore). I noticed the same behavior when I created a new SqliteConnection without using EFCore.

Desperate, I deleted the DB and recreated it from scratch using Microsoft.Data.Sqlite. Obviously there was no EFCore information in this DB. Then I filled the DB with some test records and went to use it. No more disappearing records.

There seemed to be something very odd about the way EFCore set up the database in the first place causing the problem. But I don't know what it was.

+3


source to share


1 answer


What is probably happening is that you are using CodeFirst / w EF but are using the DB approach first when it comes to testing your new code. EF keeps track of schema changes in the database, and my guess is that by creating the table ahead of time, it doesn't know the schema is validated, so it crashes and recreates it when the context starts.

The fix is ​​to create a "stub" test that populates the test record once using your EF model. From there, you should have a table that EF recognizes in this context and accepts. From there, you can create test records in any editor for testing purposes.



SQLite has several limitations associated with schema migration, which you probably want to consider. (see: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations )

You might be better off setting up the DB first by telling EF how to map the existing SQLite schema rather than trying Code-First as migration is pretty limited for that DB engine.

+3


source







All Articles