Usuário com melhor resposta
Erro EF com mensagem "has no key defined. Define the key for this EntityType"

Pergunta
-
Pessoal estou fazer uma pequena aplicação em C# MVC3 com EF, e está dando o erro:
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'CNAES' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet ?CNAES? is based on type ?CNAES? that has no keys defined.
O model está abaixo:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ERP.Models { public class CNAES { public int CNAEID { get; set; } public string Descricao { get; set; } } }
Controler
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using ERP.Models; namespace ERP.Controllers { public class CNAESController : Controller { // // GET: /CNAES/ private ERPCodeFirstContext db = new ERPCodeFirstContext(); public ActionResult Index() { return View(db.CNAES.ToList()); } } }
View
@model IEnumerable<ERP.Models.CNAES> @{ ViewBag.Title = "Index"; } <h2>Index</h2> @foreach (var item in Model) { @Html.DisplayFor(modelItem => item.Descricao) <br/> }
Abs
Marlon Tiedt
www.sesmt.com.br
Respostas
-
Olá Marlon,
Adicione o DataAnnotation Key.
public class CNAES { [Key] public int CNAEID { get; set; } public string Descricao { get; set; } }
[]s!Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique- Marcado como Resposta Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator sexta-feira, 1 de junho de 2012 17:51
-
Olá Marlon,
Se vc já tem a base de dados criada, então vc tem que fazer assim:
namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } public ERPCodeFirstContext() { Database.SetInitializer(null); } } }
E tb não pode utilizar o DropCreateDatabaseIfModelChanges, como estava antes no seu Global.asax.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
- Editado Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator sexta-feira, 1 de junho de 2012 16:52 Correção de código.
- Marcado como Resposta Marlon Tiedt sexta-feira, 1 de junho de 2012 17:45
-
Olá Fernando,
consegui fazer funcioanr desta maneira, conforme código abaixo:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } public ERPCodeFirstContext() { Database.SetInitializer<ERPCodeFirstContext>(null); } } }
Vi que no seu blog tem este assunto na url clique aqui.
Tá certo da maneira acima como coloquei?
Abs...
Marlon Tiedt
www.sesmt.com.br- Marcado como Resposta Marlon Tiedt sexta-feira, 1 de junho de 2012 17:44
Todas as Respostas
-
Olá Marlon,
Adicione o DataAnnotation Key.
public class CNAES { [Key] public int CNAEID { get; set; } public string Descricao { get; set; } }
[]s!Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique- Marcado como Resposta Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator sexta-feira, 1 de junho de 2012 17:51
-
Tks Fernando...
Agora somente não aparece os dados. :) Tentando ver o que está acontecendo.
Minha view está assim:
@model IEnumerable<ERP.Models.CNAES> @{ ViewBag.Title = "Index"; } <h2>Marca</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table> <tr> <th> Nome </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Descricao) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.CNAEID }) | @Html.ActionLink("Details", "Details", new { id = item.CNAEID }) | @Html.ActionLink("Delete", "Delete", new { id = item.CNAEID }) </td> </tr> } </table>
Marlon Tiedt
www.sesmt.com.br -
Olá Marlon,
Neste caso acho melhor criar uma Thread no fórum de ASP.Net MVC.
Mas vc consegue ver se os dados estão sendo retornados da base de dados?
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique -
Fernando, descobri o problema.
No Global.asax tenho o código:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using System.Data.Entity; using ERP.Models; namespace ERP { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); Database.SetInitializer<ERPCodeFirstContext>(new DropCreateDatabaseIfModelChanges<ERPCodeFirstContext>()); } } }
O problema era que tinha dado outro nome para a conexão no Web.config
Estava assim:
<connectionStrings> <add name="ERP" connectionString="Data Source=E020\SQLEXPRESS;Initial Catalog=SESMT;User ID=automa; Password=automa" providerName="System.Data.SqlClient"/> </connectionStrings>
E deveria ser assim:
<connectionStrings> <add name="ERPCodeFirstContext" connectionString="Data Source=E020\SQLEXPRESS;Initial Catalog=SESMT;User ID=automa; Password=automa" providerName="System.Data.SqlClient"/> </connectionStrings>
Agora parece que ele conecta e tenta buscar os dados.
Porém agora tem o erro:
Model compatibility cannot be checked because the database does not contain model metadata. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.Erro está aqui:
Line 17: public ActionResult Index() Line 18: { Line 19: return View(db.CNAES.ToList()); Line 20: } Line 21:
Abs
Marlon Tiedt
www.sesmt.com.br -
Olá Marlon,
No seu Datacontext vc tem a linha abaixo? Se não, poste o código do seu DataContext.
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
[]s!Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique -
Olá Fernando,
Como não sei aonde está isto estou postando o código abaixo do DBContext:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } } }
Subi aqui o projeto completo.
http://www.sesmt.com.br/ERP.rar
Abs
Marlon Tiedt
www.sesmt.com.br -
Olá Marlon,
No seu caso recomendo fazer o seguinte:
1 - Remover a linha "Database.SetInitializer<ERPCodeFirstContext>(new DropCreateDatabaseIfModelChanges<ERPCodeFirstContext>());" do StartUp do seu projeto
2 - Substituir seu contexto por:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } public ERPCodeFirstContext() { if (Database.Exists()) Database.SetInitializer(new DropCreateDatabaseAlways<ERPCodeFirstContext>()); else Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ERPCodeFirstContext>()); } } }
Vamos testar desta forma...
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique -
Fernando, estou achando que o problema está na conexão. Eu já tenho a base criada e não gostaria que o sistema mexe-se nisto.
O erro que retorna agora é: CREATE DATABASE permission denied in database 'master'.
Além disto o código dropou base inteira.
AbsMarlon Tiedt
www.sesmt.com.br -
http://blogs.msdn.com/b/dparys/archive/2009/09/17/create-database-permission-denied-in-database-master-my-fix.aspx
O Amor que Sinto por Ti, Apenas Deus e capaz de sentir e superar tal amor!
-
Olá Marlon,
Se vc já tem a base de dados criada, então vc tem que fazer assim:
namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } public ERPCodeFirstContext() { Database.SetInitializer(null); } } }
E tb não pode utilizar o DropCreateDatabaseIfModelChanges, como estava antes no seu Global.asax.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
- Editado Fernando Henrique Inocêncio Borba FerreiraMicrosoft employee, Moderator sexta-feira, 1 de junho de 2012 16:52 Correção de código.
- Marcado como Resposta Marlon Tiedt sexta-feira, 1 de junho de 2012 17:45
-
Olá Fernando,
consegui fazer funcioanr desta maneira, conforme código abaixo:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace ERP.Models { public class ERPCodeFirstContext : DbContext { public DbSet<CNAES> CNAES { get; set; } public ERPCodeFirstContext() { Database.SetInitializer<ERPCodeFirstContext>(null); } } }
Vi que no seu blog tem este assunto na url clique aqui.
Tá certo da maneira acima como coloquei?
Abs...
Marlon Tiedt
www.sesmt.com.br- Marcado como Resposta Marlon Tiedt sexta-feira, 1 de junho de 2012 17:44
-
Sim, esta perfeito.
Desta forma vc esta correto, é este o modo como vc deve fazer quando não quer que o EF crie a base de dados para vc.
Eu queria dizer justamente isso no post anterior, mas não prestei atenção e fiz besteira.
Mas assim esta ok, desta forma o EF entende que vc não quer criar a base de dados automaticamente, e sim respeitar a base que ja existe.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique -
-
Olá Marlon,
Vou marcar a resposta com o atributo Key como resposta, pois ela efetivamente é a resposta para sua pergunta inicial.
Isso vai ajudar os próximos leitores.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique