Entity Framework 6 does not create database

6

I created a C # WEB MVC5 project in Visual Studio 2013, installed the entity framework 6 and created my classes ("entities") as well as the DBContext with their DBsets.

Within WEB.Config I configured my connection string and in the DBContext I pointed to the connection string created. Although I have followed all the steps of the handouts I read, when running my web project the blessed database is not created ... until initializer I created it.

Server, User, and Bank Server password are correct ... I can not find a single code breakthrough that does not work!

Classes ...

Level_Access

    public class Nivel_Acesso
    {
     public int Nivel_AcessoID { get; set; }
     public String Nivel { get; set; }
     public ICollection<Acesso> Acesso { get; set; }
    }

Access

    public class Acesso
    {
      public int AcessoID { get; set; }
      [ForeignKey("Nivel_AcessoID")]
      public int Nivel_AcessoID { get; set; }
      public String Usuario { get; set; }
      public String Senha { get; set; }        
    }

ClinicaDBContext

    public class ClinicaDBContext : DbContext 
    {
    public ClinicaDBContext() : base("Conexao"){}
        public DbSet<Nivel_Acesso> Nivel_Acesso { get; set; }
        public DbSet<Acesso> Acesso { get; set; }

    }

Web.config

      <connectionStrings>
       <add name="Conexao" providerName="System.Data.SqlClient"
        connectionString="Server=.;Database=Clinica;User Id=sa;" />
       </connectionStrings>

My server does not have a password!

For those of you who want to check the entire code, please provide the project link:

link

    
asked by anonymous 26.11.2014 / 11:52

2 answers

7

First of all, your solution is outdated. You need to update all packages in the solution. Open the Package Manager Console and enter the following:

  

PM > Update-Package

There was some weird problem with your packages, so I had to delete the packages directory of the solution and create it again through the same command. You may need to close and reopen the next pro solution.

Code First is not enabled in the project. It means that there is no support for Migrations (incremental bank migrations), nor the control of context modifications. Open the Package Manager Console and enter the following:

  

PM > Enable-Migrations

Configuration creation caught this error:

  

The property 'Access_ID' can not be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.

It means that you have set up a wrong ID, that is, a real benchmark, and the Entity Framework understands the ID as a navigation property, which is just one more property to load other information from related entities. I needed to change the following:

namespace SistemaC.Models
{
    public class Acesso
    {
        [Key]
        public int AcessoId { get; set; }
        public int NivelAcessoId { get; set; } // Isto é uma informação de banco.

        [Required]
        public String Usuario { get; set; }
        [DataType(DataType.Password)]
        public String Senha { get; set; }

        public virtual NivelAcesso NivelAcesso { get; set; } // Isto é um atributo de navegação.
    }
}

Notice that I took [ForeignKey("Nivel_AcessoID")] . It is for navigation properties, not for key properties. Because its design is very simple, the Entity Framework knows how to identify navigation properties by itself and by the nomenclature. You can, therefore, not use the attribute.

Likewise, I changed NivelAcesso :

namespace SistemaC.Models
{
    public class NivelAcesso
    {
        [Key]
        public int NivelAcessoId { get; set; }
        public String Nivel { get; set; }

        public virtual ICollection<Acesso> Acessos { get; set; }
    }
}

Name matching does not use "_" in object names. Another thing I needed to do is identify what the Model key is with the [Key] attribute.

ICollections related are always with names in the plural, so you know during programming that you are dealing with a collection, not with an object only.

The context looks like this:

namespace SistemaC.Models
{
    public class ClinicaDbContext : DbContext 
    {
        //public ClinicaDBContext()
        //{
        //    Database.SetInitializer<ClinicaDBContext>(new CreateDatabaseIfNotExists<ClinicaDBContext>());
        //}
            public DbSet<NivelAcesso> NivelAcessos { get; set; }
            public DbSet<Acesso> Acessos { get; set; }
    }
}

Everything also in the plural.

I needed to delete the DBInit.cs . He was totally wrong. The Global.asax looks like this:

namespace SistemaC
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}

Fixed this, I was able to generate the first Migration one that actually installs the database, like this:

  

PM > Initial Add-Migration

Generated:

namespace SistemaC.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class Inicial : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Acessoes",
                c => new
                    {
                        AcessoId = c.Int(nullable: false, identity: true),
                        NivelAcessoId = c.Int(nullable: false),
                        Usuario = c.String(nullable: false),
                        Senha = c.String(),
                    })
                .PrimaryKey(t => t.AcessoId)
                .ForeignKey("dbo.NivelAcessoes", t => t.NivelAcessoId, cascadeDelete: true)
                .Index(t => t.NivelAcessoId);

            CreateTable(
                "dbo.NivelAcessoes",
                c => new
                    {
                        NivelAcessoId = c.Int(nullable: false, identity: true),
                        Nivel = c.String(),
                    })
                .PrimaryKey(t => t.NivelAcessoId);

        }

        public override void Down()
        {
            DropForeignKey("dbo.Acessoes", "NivelAcessoId", "dbo.NivelAcessoes");
            DropIndex("dbo.Acessoes", new[] { "NivelAcessoId" });
            DropTable("dbo.NivelAcessoes");
            DropTable("dbo.Acessoes");
        }
    }
}

"Gypsy, the table name is Access , not Access , and Access Levels , not Access Levels " . It's all right. Pluralization of the Entity Framework is in English. So the name. We can arrange it as follows:

namespace SistemaC.Models
{
    [Table("Acessos")]
    public class Acesso
    { ... }
}

namespace SistemaC.Models
{
    [Table("NiveisAcessos")]
    public class NivelAcesso
    { ... }
}

Result:

namespace SistemaC.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class Initial : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Acessos",
                c => new
                    {
                        AcessoId = c.Int(nullable: false, identity: true),
                        NivelAcessoId = c.Int(nullable: false),
                        Usuario = c.String(nullable: false),
                        Senha = c.String(),
                    })
                .PrimaryKey(t => t.AcessoId)
                .ForeignKey("dbo.NiveisAcessos", t => t.NivelAcessoId, cascadeDelete: true)
                .Index(t => t.NivelAcessoId);

            CreateTable(
                "dbo.NiveisAcessos",
                c => new
                    {
                        NivelAcessoId = c.Int(nullable: false, identity: true),
                        Nivel = c.String(),
                    })
                .PrimaryKey(t => t.NivelAcessoId);

        }

        public override void Down()
        {
            DropForeignKey("dbo.Acessos", "NivelAcessoId", "dbo.NiveisAcessos");
            DropIndex("dbo.Acessos", new[] { "NivelAcessoId" });
            DropTable("dbo.NiveisAcessos");
            DropTable("dbo.Acessos");
        }
    }
}

Finally, update the database with the command:

  

PM > Update-Database

The database will be created with the tables, according to the source pointed out in its Connection String . In fact, I had to change it slightly to allow authentication with Windows and I do not need to use the user sa :

<connectionStrings>
  <add name="ClinicaDBContext" providerName="System.Data.SqlClient" connectionString="Server=.\SQLEXPRESS;Database=Clinica;Integrated Security=SSPI;MultipleActiveResultSets=true;" />
</connectionStrings>

Done that, compiled with bank and everything. You can download the fonts here .

    
28.11.2014 / 00:16
4

In the constructor of your DBContext class try to add the following code statement.

public class ClinicaDBContext : DbContext 
{
   public ClinicaDBContext() : base("Conexao")
   {
      Database.SetInitializer<ClinicaDBContext>(new CreateDatabaseIfNotExists<ClinicaDBContext>());
   }     

   public DbSet<Nivel_Acesso> Nivel_Acesso { get; set; }
   public DbSet<Acesso> Acesso { get; set; }
}

Also check that within your Web.config file you have the class initialization statement, as in the example below:

<entityFramework>
  <contexts>
    <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
      <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
    </context>
  </contexts>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="v11.0" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

I hope I have helped.

    
26.11.2014 / 12:31