Problem to create database using Entityframework with configuration by Dbconfiguration

Asked

Viewed 437 times

1

I’m studying the Entityframework, writing two contexts to understand how to handle it when my domain contains many classes of entity. Which would then be represented by many Dbset s in context, making "heavy" their initialization.
I imagine this is the right way to work when you have a model with many classes!

Then I started my tests by writing the following domain, solely for testing:

public class Empresa
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [StringLength(70)]
    public string RazaoSocial { get; set; }
}

public class Usuario
{
    [Key]
    [StringLength(150)]
    public string Login { get; set; }

    [StringLength(50)]
    [DataType(DataType.Password)]        
    public string Senha { get; set; }
}

The context created as follows:

public class EfConfiguration : DbConfiguration
{
    public EfConfiguration() {       
        SetProviderServices(SqlProviderServices.ProviderInvariantName, 
            SqlProviderServices.Instance);
        SetDefaultConnectionFactory(new SqlConnectionFactory());
    }
}

[DbConfigurationType(typeof(EfConfiguration))]
public abstract class CustomContext : DbContext
{
    protected CustomContext(): base("DefaultConnection") {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }
}

public class EmpresaContext : CustomContext
{
    public DbSet<Empresa> Empresas { get; set; }
}

public class UsuarioContext : CustomContext
{
    public DbSet<Usuario> Usuarios { get; set; }
}

So is the App.config from my console app for testing:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="DefaultConnection"
      connectionString="Data Source=(local);Initial Catalog=TestEF;Integrated Security=True"
      providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

Anyway, not to put a lot more code my console app for testing:

static class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Instanciando as classes ...");

            var empresaRepository = new EmpresaRepository<Empresa>();
            var usuarioRepository = new UsuarioRepository<Usuario>();

            Console.WriteLine("Obtendo ...");

            empresaRepository.Obter();
            usuarioRepository.Obter();

            Console.WriteLine("Pronto!");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.GetBaseException().Message);
        }

        Console.ReadKey();
    }
}

The methods Obter() will perform the following commands from my generic Repository class:

public IQueryable<T> Obter(Expression<Func<T, bool>> condition = null)
{
    var result = (IQueryable<T>)_context.Set<T>();
    if (condition != null)
        result = result.Where(condition);
    return result;
}

My problem is that the string "Done!" of the last command Console.WriteLine() is printed on the Windows console but the database is not being created. Anyway, no error message is being printed!

What could be causing this?

Obs: Without using the DbConfiguration and writing App s with EF in the traditional way have no problems.


EDIT

Following user guidelines Gypsy Morrisson tried to specify the creation of the bank using initializers for the context:

Database.Setinitializer(new Dropcreatedatabasealways()); Database.Setinitializer(new Dropcreatedatabasealways());

Unfortunately it didn’t work either!

Then I tried also with Migrations. For more than one context I needed to specify:

Enable-Migrations -ContextTypeName EmpresaContext -MigrationsDirectory Migrations\EmpresaContext
Enable-Migrations -ContextTypeName UsuarioContext -MigrationsDirectory Migrations\UsuarioContext

Adding version:

Add-Migration -ConfigurationTypeName AppConsoleTest.Migrations.EmpresaContext.Configuration "Initial"
Add-Migration -ConfigurationTypeName AppConsoleTest.Migrations.UsuarioContext.Configuration "Initial"

Creating and updating databases:

Update-Database -ConfigurationTypeName AppConsoleTest.Migrations.EmpresaContext.Configuration
Update-Database -ConfigurationTypeName AppConsoleTest.Migrations.UsuarioContext.Configuration

Thus the database was created. Both reached the same database and the two tables appeared.

Soon, I tried commenting //[DbConfigurationType(typeof(EfConfiguration))] of CustomContext, I removed the files from Migrations and also removed the initializers Database.SetInitializer and when executing the application, in the methods Obter() of the repository objects (empresaRepository and usuarioRepository) the base is created and the tables are also in the same bank.
With this I deduced that the error is in my configuration class, the EfConfiguration.

What is wrong?

1 answer

1

You have not specified in any way how this(s) context(s) should(m) be created(s).

There are some ways:

1. Enabling Migrations

In Visual Studio, go to View > Other Windows > Package Manager Console. At the prompt that appears, type the following:

Enable-Migrations -Enableautomaticmigrations

He may ask you to specify what context you want migrations. Done that, type:

Initial Add-Migration

A migration initial, containing all entities that must be created in your database. To effectively create these entities, type:

Update-Database

The code should work smoothly if everything was done right.

2. Use a setting that does not require migrations

In this case, you will need to configure your context(s) to have database initializers. That is, put the following code in your Main or in its context:

Database.SetInitializer(new DropCreateDatabaseAlways<EmpresaContext>());
Database.SetInitializer(new DropCreateDatabaseAlways<UsuarioContext>());
  • With the Database.SetInitializer(..) didn’t work out. I’m looking for the name of the command to specify a folder for Migrations, for each context, so it allows more than one and then I can test. Otherwise it asks for which context to create and then does not allow creating for the other later.

  • Good. With Migrations and using a single context the base is created without problems with the command update-database. But.. a question, shouldn’t create alone? EF no longer creates alone, no extra settings?

  • Right, with Migrations for both contexts also creates the database.

  • Answering your question about creating alone: no, you shouldn’t create alone, because the application doesn’t know where to start. It can use SQL Server Express, Localdb or a base from some other provider. Therefore, it is the programmer who needs to indicate the path.

  • 2

    Because I removed the decorator //[DbConfigurationType(typeof(EfConfiguration))] of CustomContext, I removed Migrations and Database.SetInitializer and it worked! And yet the project creates itself as soon as the command Obter() is called. Also, I discovered with that the problem is in my DbConfiguration. Grateful!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.