0

So I'm working on an application that is using Entity Framework 7 and SQLite to store various pieces of data. I'm running into an issue with EF not creating the second table in my test.db file. I have a hunch that it's because both context's are setting the datasource to test.db

var connectionStringBuilder = new SqliteConnectionStringBuilder {DataSource = "test.db"};

I'm not sure if this would cause an issue or not as I'm not familiar with EF or SQLite and this is the first ORM that I've worked with. Below I have two example enity's with their respective context's.

[Table("MyEntity")]
public class MyEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public string MyColumn { get; set; }
    public int MyNumber { get; set; }
}

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

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connectionStringBuilder = new SqliteConnectionStringBuilder {DataSource = "test.db"};
        var connectionString = connectionStringBuilder.ToString();
        var connection = new SqliteConnection(connectionString);

        optionsBuilder.UseSqlite(connection);
    }
}

[Table("MySecondEntity")]
public class MySecondEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public string MyColumn { get; set; }
    public int MyNumber { get; set; }
}

public class MySecondContext : DbContext
{
    public DbSet<MySecondEntity> MyTable2 { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = "test.db" };
        var connectionString = connectionStringBuilder.ToString();
        var connection = new SqliteConnection(connectionString);

        optionsBuilder.UseSqlite(connection);
    }
}

These two entities and their contexts are in separate C# files. And both are being referenced in Program.cs. Below you'll find the code that's in my Program.cs file.

static void Main(string[] args)
    {
        using (var db = new MyContext())
        {
            db.Database.EnsureCreated();

            PopulateData(db);
            CheckValues(db);
        }

        using (var db = new MySecondContext())
        {
            db.Database.EnsureCreated();

            PopulateDataTwo(db);
            CheckValuesTwo(db);
        }

        WaitForCompletion();
    }  

    private static void PopulateData(MyContext db)
    {
        MyEntity testEntity1 = new MyEntity();

        testEntity1.MyColumn = "Test Data 1";
        testEntity1.MyNumber = 12345;

        db.Add(testEntity1);
        db.SaveChanges();
    }

    private static void PopulateDataTwo(MySecondContext db)
    {
        MySecondEntity entity1 = new MySecondEntity();

        entity1.MyColumn = "New Data 1";
        entity1.MyNumber = 2;

        db.Add(entity1);
        db.SaveChanges();
    }

    private static void CheckValues(MyContext db)
    {
        Console.WriteLine("Inserting Data...");

        Console.WriteLine("Data in the Database");
        foreach (var entity in db.MyTable)
        {
            WriteToConsole("Id: " + entity.Id);
            WriteToConsole("Column Data: " + entity.MyColumn);
            WriteToConsole("Number: " + entity.MyNumber);
        }
    }

    private static void CheckValuesTwo(MySecondContext db)
    {
        Console.WriteLine("Inserting Data...");

        Console.WriteLine("Data in the Database");
        foreach (var entity in db.MyTable2)
        {
            WriteToConsole("Id: " + entity.Id);
            WriteToConsole("Column Data: " + entity.MyColumn);
            WriteToConsole("Number: " + entity.MyNumber);
        }
    }

    public static void WriteToConsole(string msg)
    {
        Console.WriteLine(msg);
    }

    private static void WaitForCompletion()
    {
        WriteToConsole("Examples run finished,press Enter to continue...");
        Console.ReadLine();
    }

I have a feeling that it's just something simple I'm missing, when I run this code I get the below error. The error happens in the db.SaveChanges(); call in PopulateDataTwo().

Message=An error occurred while updating the entries. See the inner exception for details. Message=SQLite Error 1: 'no such table: MySecondEntity'

I don't see anything different between the two entity classes other than the name that would indicate an issue with why it wouldn't be able to create the second table. Does each context need to point to a unique datasource?

CGideon
  • 143
  • 2
  • 15

1 Answers1

2

You must use migrations. Ensure created is for testing only

ErikEJ
  • 40,951
  • 5
  • 75
  • 115
  • Thanks! Is this something that can be done via code? I'm not sure of how migrations with EF work. Do you have an example? – CGideon Nov 02 '15 at 22:03
  • Sure, you can do context.Database.Migrate() – ErikEJ Nov 02 '15 at 22:42
  • Thanks @ErikEj that was exactly what was needed! Still running into a problem when trying to select data out of the table, it's saying it doesn't exist but that seems to be a separate issue. – CGideon Nov 03 '15 at 14:00
  • NOT sure that multiple contexts are supported in a single db file – ErikEJ Nov 03 '15 at 17:10
  • It does appear that it is possible via the Package Manager console according to http://www.codeproject.com/Tips/801628/Code-First-Migration-in-Multiple-DbContext unfortunately it looks like this is not possible with a Code First approach http://stackoverflow.com/questions/11197754/entity-framework-one-database-multiple-dbcontexts-is-this-a-bad-idea – CGideon Nov 03 '15 at 20:03
  • Maybe, but your links do not apply to EF7, but are EF6 releated – ErikEJ Nov 04 '15 at 11:02
  • Unfortunately since EF7 is in beta still I can't seem to find much documentation for it. I'd think it'd be possible by just having multiple DBSet in a single context but I'm still running into issue with EF not creating the table. I _think_ it may be an issue that can be solved with a custom IDatabaseInitializer implementation to check the DB for the tables and create them if necessary. – CGideon Nov 04 '15 at 14:51