Entity Framework 6 does not create database

Asked

Viewed 3,589 times

6

I created a c# WEB MVC5 project in visual studio 2013, installed Entity framework 6 and created my classes("entities") as well as Dbcontext with the respective Dbsets.

Inside the WEB.Config I set up my connection string and in Dbcontext I pointed out 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.

Server, User and password of the database server are correct... I can not find a single breach for code not work!

Classes...

Access level

    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 has no password!

For those who want to check the whole code, I provide the project link:

http://www.4shared.com/rar/L3lsmYrvce/SistemaC.html

  • Face your connection string is automatically generated, it is not generating your EDMX?

  • Automatically generated? did not know it and even about EDMX I had no knowledge. I read a series of handouts and none of them quoted the EDMX, now that you spoke I did a search and found out what it is, however if the . edmx is listed in the directory structure, it has not been created.

  • this tutorial is very good, follow the step by step you will be able to create. http://www.macoratti.net/11/09/ef4_mp1.htm

  • it is generated in the structured directory. it shows you the database template. as well as its generated objects through its tables.

  • From what I can see, the. edmx is created from an existing base... but in my case, the intention is to generate a base from my created entities.

  • Do I understand you’re doing the reverse way? More because this?

  • Ué... because the great attraction of the ORM is precisely this, not to worry about coding SQL and missing the need to build database structures inside the server.

  • Cleiton, try it this way. If it works I put in response: In your Connection string instead of putting this name "Connection", put the name of your Dbcontext, ie, "Clinicadbcontext". Just to see if it works. And see later, because its string connection is actually automatically generated !

  • I had already tried that and also it did not work... I tried again and also did not give any result.

  • I added the project download link.

  • Cleiton I opened your project and saw that much is missing, and also the way it is being done will not create the database according to your classes. I found a good tutorial that can help you, which teaches from the beginning of the project. http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

  • What is missing, for example? I already have the model classes, I already have Webconfig configured and with connection string, I already have the Dbcontext class with the proper dbsets, I already have a controller that offers access to my main view... I had already consulted this page, but found no discrepancy.

  • Cleiton a tip for you that learning: go to the official website and do the Getting Started... It is better to do it from the beginning. There it will surely help you to find your mistake.

  • I will download your code here and I already answer. You do not prefer to use a Github or something that is easier for people to suggest modification in your code?

Show 9 more comments

2 answers

7


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

PM> Update-Package

There was some weird problem with your packages, so I had to delete the directory packages solution and create again through the same command. It may be necessary to close and reopen the following pro solution.

The Code First is not enabled in the project. It means that there is no support for Migrations (incremental database migrations), or context modification control. Open the Package Manager Console and type in the following:

PM> Enable-Migrations

Setting up the setting caught this error:

The Property 'Nivel_acessoid' cannot 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 set up a wrong ID, that is, a real database parameter, and the Entity Framework understood 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 I took [ForeignKey("Nivel_AcessoID")]. It serves for navigation properties, not key properties. As its project is very simple, the Entity Framework knows how to identify navigation properties by itself and by naming them. You can therefore not use the attribute.

In the same way, 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; }
    }
}

The convection of names does not use "_" in object names. Another thing I needed to do is identify which is the key to the Model with the attribute [Key].

ICollections related are always with plural names, so you know during programming that you are dealing with a collection, and not with a single object.

The context was 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 had to erase the DBInit.cs. He was totally wrong. The Global.asax was like this:

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

Fixed that, I managed to generate the first Migration the one that actually installs the database, so:

PM> Initial Add-Migration

Spawned:

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 Accesses, nay Accessions, and Levels, nay Levels". All right. The pluralization of the Entity Framework is in English. That’s why the name. We can arrange as follows:

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

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

Upshot:

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 base with the command:

PM> Update-Database

The bank will be created with the tables, according to the origin pointed in its Connection String. In fact, I needed to change it slightly to allow authentication with Windows and I didn’t 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 all. You can download the fonts here.

4

in the constructor of your Dbcontext class try to add the following code instruction.

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 inside your Web.config file has the class boot instruction, 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’ve helped.

  • hmm... :/ unfortunately it didn’t work... I added the instruction, saved and gave build. I tried to run the project, but the server continues without the clinical database.

  • Friend, put a breakpoint in the code I passed you, inside the constructor and see if in the execution of the project the code snippet will be executed.

  • Apparently, he doesn’t even get into the Clinicadbcontext class.

  • This class has to be instantiated if not your database will not be created. Is the tutorial you are following online? If it is, can pass me so I can help you better?

  • I downloaded a booklet from K19 and downloaded the course material from a friend, in none of these materials there is the instruction where to instantiate and call the context. I followed the step by step and on no Internet Tuto I saw the context being instantiated. http://www.k19.com.br/cursos/desenvolvimento-web-com-aspnet-mvc

  • I ran some tests here and found something that may be missing from your code. Check whether inside Web.config has the instruction to initialize the class. I will edit the answer by adding an example.

  • Not for sure Ton :/ but thank you

Show 2 more comments

Browser other questions tagged

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