Sono appena iniziato con Entity Framework 4.1, provando la modalità "database first". Quando EF genera una classe Model con il "Generatore DbContext di ADO.Net", non dovrebbe identificare la chiave primaria per la classe con un attributo [Chiave]? In caso contrario, appare incompatibile con il T4 MVCScaffolding.Entity Framework 4.1 Database First non aggiunge una chiave primaria alla classe generata da DbContext T4
Ecco i dettagli:
utilizzando la GUI Designer Entity Data Model, ho aggiunto un semplice "country" tabella per il modello dal mio database esistente. La GUI identifica correttamente un singolo campo della chiave di identità intero chiamato "PK" come chiave primaria. (Ahimè, sono un nuovo utente, quindi non posso aggiungere uno screenshot. Ho incluso il CSDL invece di seguito.) Tuttavia, quando EF genera codice usando "ADO.Net DbContext Generator", non identifica il PK campo come campo chiave nella classe generata (vedere l'estratto del codice di seguito).
Il CSDL per la tabella "paese":
<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>
Ecco il codice generato automaticamente:
//------------------------------------------------------------------------------
// <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; }
}
}
Ciò causa un problema quando cerco di patibolo un controller utilizzando il modello MVCScaffolding T4. Viene visualizzato un messaggio di errore "Nessuna proprietà sembra essere la chiave principale". Il comando e uscita dalla Console NuGet Gestione pacchetti è inferiore:
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
Tuttavia, se cambio manualmente la classe generata per aggiungere un attributo [Key] per il campo, quindi l'esatto comando stesso ponteggio mostrato sopra funziona bene :
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; }
}
}
Allora, perché non sono EF database primo e l'T4 MVCScaffolding giocando bello insieme? E anche senza il problema dello scaffolding, le classi EF non devono sapere quali sono i campi chiave?
Grazie Ladislav. La modifica dei modelli T4 è al di là di ciò che voglio tentare in questo momento. Ho provato le classi buddy (seguendo http://stackoverflow.com/questions/4915957/using-system-componentmodel-dataannotations-with-entity-framework-4-0/) e sebbene potessi compilare e creare il progetto senza errori, il pacchetto MVCScaffolding non funzionava ancora. Ho aggiunto questo come argomento di discussione nel progetto CodePlex MVCScaffolding (http://mvcscaffolding.codeplex.com/discussions/284993). Code First non è un'opzione perché sto mappando su un grande DB esistente. –
Non è disponibile alcuna versione modificata del modello T4? – Saber