Question

I am using MVC5 & EF6. I am doing code-first approach. I have some tables that require to be generated using migration (works) and some tables that I need to use from existing database - tables.

in the DbContext class I have

    'new table that is created in the DB (works)  
    public DbSet<Subscription> Subscriptions { get; set; }
    public DbSet<Memeber> Members { get; set; }
    'existing table. 
    public DbSet<CodeTable> CodeTable { get; set; }

in the Configuration- (Migration folder)

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

what it does now, it creates a new table called CodeTables

  1. It becomes plural, why is that?- Can it be turned off?
  2. How do I use the CodeTable and not generated new table?
  3. When I delete manually table that was generated using codefirst i.e. Member table. Then I run

Update-Database -Verbose -Force (That doesnt do anything)
Using StartUp project 'Test'.
Using NuGet project 'Test'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'TESTDB' (DataSource: 10.10.50.89, Provider:
System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Running Seed method.

and then run the application, I get an exception
System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'dbo.Members'. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception

because the table not found. Table does not get generated.

How do I let it know that if table not found. Create it?

I noticed if I delete __MigrationHistory and then run the Update-Database. It then complains about my other tables that exists
There is already an object named 'Subscriptions' in the database.
and it only works if I delete all my tables. But this seems to be silly, deleting all tables. I hope there is another approach.

1
0
2/24/2016 3:24:48 PM

Accepted Answer

To use code first with an existing database you need to do two things: 1) specify your connection string and 2) turn off the database initialization strategy. Those two things can be achieved with the following context sample:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext()
        : base("ConnectionStringName")
    {
        Database.SetInitializer<ApplicationDbContext>(null);
    }

    // DbSets here
}

Now, by convention, Entity Framework assumes your table names are pluralized forms of the entity class name. If the table name is not plural and/or it is not the same as the entity class name, then you can use the Table attribute to specify exactly what it should be:

[Table("foo_table")]
public class Foo
{
    // properties
}

Likewise, if your column names do not match up with your property names, you can use the Column attribute to specify those:

[Column("strFoo")]
public string Foo { get; set; }

UPDATE

On first reading, I didn't pay attention to the fact that you're trying to mix and match existing tables with tables generated by code first. You cannot do this. Since using an existing database/existing tables requires disabling the initialization strategy, either all the tables in that database must be existing or Entity Framework must generate all the tables. You can't go halfway.

If you need to utilize some existing tables and have EF create some, you need two databases and two contexts, one where EF will generate everything via code first, and another where the initialization strategy is off and you're responsible for the database and tables. Importantly, this means you can not mix and match these. All your code first entities can not reference any of your existing database entities via navigation properties, or they will be implicitly added to the code first context and EF will generate the tables.

The best you can do is to have a regular property that holds the id of the related entity, and then manually use this id to look up the entity from the existing database context. In other words, it will not be a true foreign key, and you will not be able to utilize lazy-loading, etc.

1
2/24/2016 3:40:10 PM

Popular Answer

I do it differently - I create one large context with ALL tables I will ever need - and do migrations/DB updates on that context. And then create several "read-only" contexts - in the sense that I call Database.SetInitializer(null) - meaning they will not have migrations etc - and add only necessary DbSet there. This way I can achieve exactly what you are describing.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow