42

J'essaie d'utiliser le modèle de référentiel avec EF4 en utilisant VS2010. Pour cela, j'utilise la génération de code POCO en cliquant avec le bouton droit de la souris sur le concepteur de modèle d'entité et en cliquant sur Ajouter un élément de génération de code. Je sélectionne ensuite le modèle POCO et récupère mes cours. Ce que je voudrais être capable de faire est de structurer ma solution en projets séparés pour les classes Entité (POCO) et un autre projet pour le modèle d'entité et le code du référentiel.Générer des classes POCO dans différents projet au projet avec le modèle Entity Framework

Cela signifie que mon projet MVC pourrait utiliser les classes POCO pour les vues fortement typées, etc. et ne pas avoir à connaître le référentiel ou avoir une référence à celui-ci.

Pour brancher tout cela ensemble, je vais avoir un autre projet distinct avec des interfaces et utiliser IoC.

Ça me semble bon, je ne sais pas comment générer les classes dans leur propre projet! Je peux les copier et ensuite changer les espaces de noms sur eux mais je voulais éviter le travail manuel chaque fois que je change le schéma dans la base de données et que je veux mettre à jour mon modèle.

Merci

Répondre

38

En fait, les modèles T4 dans EF 4.0 ont été conçus avec ce scénario à l'esprit :)

Il y a 2 modèles:

  • Un pour les entités elles-mêmes (c.-à-ModelName.tt)
  • Un pour ObjectContext (c.-à-ModelName.Context.tt)

Vous devez placer le fichier ModelName.tt dans votre projet POCO et simplement modifier le modèle pour qu'il pointe vers le fichier EDMX dans le projet de prise en charge de la persistance.

Sons étranges Je sais: Il y a maintenant une dépendance, mais c'est au moment de la génération T4, pas au moment de la compilation! Et ça devrait aller? Parce que l'ensemble POCO résultant est encore complètement ignorant la persistance.

Voir les étapes 5 & 6 de cette: http://blogs.msdn.com/adonet/pages/walkthrough-poco-template-for-the-entity-framework.aspx pour plus d'informations.

Hope this helps

Alex

+0

Lien vers la page du blog msdn introuvable –

+0

@AmrElgarhy Archive Internet à la rescousse! Commander [http://web.archive.org/web/20110609064124/http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity- framework.aspx] (http://web.archive.org/web/20110609064124/http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the -entity-framework.aspx) – natenho

+0

Vous monsieur êtes une légende! : D – MickyD

6

@ Nick,

  1. Pour forcer la régénération des entités POCO, il vous suffit de cliquer droit sur le fichier principal .tt et sélectionnez « Exécuter Outil personnalisé ". Cela l'obligera à régénérer vos classes POCO avec vos modifications mises à jour du modèle .edmx.
  2. Y at-il un problème avec vous en allant de l'avant et en cliquant-droit sur le modèle et en sélectionnant "Générer la base de données à partir du modèle ..." même si vous ne générez pas nécessairement la base de données? Cela vous débarrassera probablement de votre 'Erreur 11007 ...'. Je pense que c'est l'équivalent d'un "code derrière". Je ne sais pas plus que ça.

Une autre chose à noter au sujet du lien qu'Alex a donné. Une fois j'ai déménagé mon principal.tt dans un autre projet, le fichier généré à partir du fichier ".Context.tt" ne compilait pas car il manquait des références aux fichiers POCO qui se trouvaient dans un espace de noms différent (car je voulais que mon ObjectContext soit dans un domaine différent de mes fichiers POCO). J'ai dû modifier le fichier ".Context.tt" pour avoir un using Poco.Namespace (où Poco.Namespace est le nom de l'espace de noms où les fichiers POCO ont été générés). Cela a ensuite permis à mon projet de se compiler.

Joel

+0

re: 2. Lors de la compilation, je reçois maintenant cet avertissement pour chaque entité: 'Erreur 11007: Le type d'entité XXXX n'est pas mappé.'. Cela peut concerner ne pas avoir généré la base de données (?) Mais cela ne se produisait pas avant le changement que j'ai édité edmx (en utilisant un éditeur xml) pour enlever le mapping qui était là (même si ça me paraissait parfait), puis retour au concepteur et ajouté la cartographie en utilisant l'outil. –

+0

J'ai eu ce * exact * même problème avec le fichier ".Context.tt" et je voulais ajouter une instruction 'using' qui a fonctionné. Le problème est que le fichier est généré automatiquement. Si le modèle doit être mis à jour, l'instruction 'using' devra être supprimée et rajoutée. Une meilleure façon de résoudre ce problème? – atconway

+0

Peu importe, juste compris après avoir regardé le lien d'Alex. Faites défiler jusqu'à la section nommée ** 7. Modifier les espaces de noms "Blogging.Context.tt" pour faire correspondre "Entités" ** L'** Espace de noms d'outil personnalisé ** sur les propriétés Context.tt peut être mis à jour pour indiquer "MyProject.Model" et les références seront résolues. – atconway

1

J'ai rencontré un bug sérieux lors de l'utilisation de cette approche combinée avec des projets et des contrôles dynamiques de données. Fondamentalement, vous obtiendrez une erreur.

Impossible de déterminer un méta-tableau Un méta-tableau n'a pas pu être déterminé pour la source de données 'EntityDataSource1' et l'URL de la demande ne permet pas de le déduire Assurez-vous que la table est mappée La source de données est configurée avec un type de contexte et un nom de table valides, ou bien la requête fait partie d'un DynamicDataRoute enregistré. "

3

Pour le générateur EF5 + DbContext: Il est facile de déplacer votre Name.Context.tt vers un autre projet. Cependant, vous devrez référencer les classes du modèle. Vous pouvez le faire manuellement, mais cela vous obligera à le changer chaque fois que le code est généré. Vous pouvez également utiliser le même espace de noms pour les deux projets. Ceci est valable et fonctionnera, mais je pense que c'est un mauvais design. Une autre alternative est de changer le template T4 (Name.Context.tt).

Modifier cette (ligne 43):

using System; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
<# 
if (container.FunctionImports.Any()) 
{ 
#> 

à ceci:

using System; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
<# 
if (modelNamespace != codeNamespace) 
#> 
using <#=code.EscapeNamespace(modelNamespace)#>; 
<# 
if (container.FunctionImports.Any()) 
{ 
#> 

Cela vérifiera si votre espace de noms de modèle diffère de votre espace de noms de code, le cas échéant, il insérera l'aide de nécessaire pour référencer vos classes de modèle.

Questions connexes