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?
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.– user7764
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?– user7764
Right, with Migrations for both contexts also creates the database.
– user7764
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.
– Leonel Sanches da Silva
Because I removed the decorator
//[DbConfigurationType(typeof(EfConfiguration))]
ofCustomContext
, I removed Migrations andDatabase.SetInitializer
and it worked! And yet the project creates itself as soon as the commandObter()
is called. Also, I discovered with that the problem is in myDbConfiguration
. Grateful!– user7764