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 .