Estoy empezando con Entity Framework 4.1, probando el modo "base de datos primero". Cuando EF genera una clase de modelo con el "ADO.Net DbContext Generator", ¿no debería identificar la clave primaria para la clase con un atributo [Key]? Sin esto, parece incompatible con el T4 MVCScaffolding.Entity Framework 4.1 La base de datos primero no agrega una clave principal a la clase generada DbContext T4
Aquí están los detalles:
utilizando la GUI de Entity Data Model Designer, he añadido una sencilla tabla de "país" con el modelo de mi base de datos existente. La GUI identifica correctamente un único campo clave de identidad entero llamado "PK" como mi clave principal. (¡Ay! Soy un nuevo usuario, así que no puedo agregar una captura de pantalla. He incluido el CSDL en su lugar a continuación). Sin embargo, cuando EF genera código usando el "ADO.Net DbContext Generator", no identifica el PK campo como el campo clave en la clase generada (ver fragmento de código a continuación).
El CSDL para la tabla de "país":
<edmx:ConceptualModels>
<Schema Namespace="EpiDataModel" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer Name="EpiModelEntities" annotation:LazyLoadingEnabled="true">
<EntitySet Name="countries" EntityType="EpiDataModel.country" />
</EntityContainer>
<EntityType Name="country">
<Key>
<PropertyRef Name="PK" />
</Key>
<Property Name="PK" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="Abbreviation" Type="String" Nullable="false" MaxLength="200" Unicode="false" FixedLength="false" />
<Property Name="Name" Type="String" MaxLength="1024" Unicode="false" FixedLength="false" />
<Property Name="Description" Type="String" MaxLength="1024" Unicode="false" FixedLength="false" />
<Property Name="Sequence" Type="Int32" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
Aquí está el código autogenerado:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace MvcApplication1.Areas.Epi.Models
{
public partial class country
{
public int PK { get; set; }
public string Abbreviation { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<int> Sequence { get; set; }
}
}
Esto causa un problema cuando trato de andamio un controlador utilizando la plantilla MVCScaffolding T4. Me sale un error "No parece que las propiedades sean claves principales". El comando y la salida de la consola NuGet Administrador de paquetes es el siguiente:
PM> scaffold controller MvcApplication1.Areas.Epi.Models.country -Area Epi -NoChildItems -DbContextType MvcApplication1.Areas.Epi.Models.EpiModelEntities -Force
Scaffolding countriesController...
Get-PrimaryKey : Cannot find primary key property for type 'MvcApplication1.Areas.Epi.Models.country'. No properties appear to be primary keys.
At C:\work\EPI\EPIC_MVC3\sandbox\MvcApplication1\packages\MvcScaffolding.1.0.6\tools\Controller\MvcScaffolding.Controller.ps1:74 char:29
+ $primaryKey = Get-PrimaryKey <<<< $foundModelType.FullName -Project $Project -ErrorIfNotFound
+ CategoryInfo : NotSpecified: (:) [Get-PrimaryKey], Exception
+ FullyQualifiedErrorId : T4Scaffolding.Cmdlets.GetPrimaryKeyCmdlet
Sin embargo, si cambio manualmente la clase generada para agregar un atributo [clave] para el campo, entonces el comando exactamente el mismo andamio se muestra más arriba funciona bien :
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; // manually added
namespace MvcApplication1.Areas.Epi.Models
{
public partial class country
{
[Key] // manually added
public int PK { get; set; }
public string Abbreviation { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<int> Sequence { get; set; }
}
}
¿Por qué no EF Database First y el T4 MVCScaffolding funcionan bien juntos? E incluso sin el problema del andamiaje, ¿las clases EF no necesitan saber cuál es el campo clave?
Gracias Ladislav. La modificación de las plantillas T4 va más allá de lo que quiero intentar en este momento. Intenté clases de compañeros (siguiendo http://stackoverflow.com/questions/4915957/using-system-componentmodel-dataannotations-with-entity-framework-4-0/), y aunque pude compilar y construir el proyecto sin errores, el paquete MVCScaffolding todavía no funcionaba. He agregado esto como un tema de discusión en el proyecto MVCScaffolding CodePlex (http://mvcscaffolding.codeplex.com/discussions/284993). Code First no es una opción porque estoy mapeando a un gran DB existente. –
¿No hay alguna versión modificada de la plantilla T4 disponible? – Saber