2010-10-19 4 views
3

Je dois modifier le modèle T4 POCO.tt pour extraire le schéma de base de données du fichier EDMX. Je peux voir le schéma stocké dans une balise EntitySet dans le XML. Cependant, je ne trouve nulle part le schéma lorsque j'utilise un objet EntitySet. Quelqu'un sait où je trouverais le schéma de base de données?Obtention du schéma à partir d'un fichier EDMX

Merci

Répondre

7

MISE à JOUR J'ai écrit mes conclusions à ce sujet dans un billet de blog:

http://www.ninjanye.co.uk/2011/06/getting-schema-information-from-edmx.html

http://jnye.co/Posts/3/getting-schema-information-from-an-edmx-file-with-poco

Je suis moi-même tombé sur ce même problème. Vous devez d'abord récupérer le EntityContainer du contenu modèle de stockage (edmx: StorageModels) section du fichier edmx

Au sommet du modèle tt (après la MetadataLoader est instancié et l'INPUTFILE est déclaré) ajoutez le code suivant pour obtenir le Modèle de stockage de contenu EntityContainer

StoreItemCollection sic; 
loader.TryCreateStoreItemCollection(inputFile, out sic); 
EntityContainer sicEntityContainer = sic.GetItems<EntityContainer>().First(); 

Ensuite, à partir du foreach (entité var dans ItemCollection.GetItems ...) boucle vous pouvez obtenir le schéma actuel avec les éléments suivants

EntitySet eset = sicEntityContainer.GetEntitySetByName(code.Escape(entity), true); 
string schemaName = eset.MetadataProperties["Schema"].Value.ToString(); 

Remarque: Vous devrez peut-être répéter le code get schéma pour les propriétés ComplexType plus bas dans le modèle tt

+0

Merci. Je n'ai pas travaillé sur cet ensemble de code depuis un certain temps, mais quand même, cette information est utile. – 37Stars

+0

'code.Escape (entity)' devrait simplement être 'entity.Name' car Escape ajoutera' @ 'si le nom est un mot-clé. En outre, ce n'est pas infaillible parce que le nom que vous passez à 'GetEntitySetByName' vient de la section edmx: ConceptualModels, alors que vous essayez de rechercher un nom sous edmx: StorageModels. Ceux-ci ne sont pas nécessairement les mêmes et sont mappés sous la section de mappage "C-S". Malheureusement, il n'y a pas d'API facile à lire cette section (voir http://social.msdn.microsoft.com/Forums/en-US/d019e830-8d3c-4e66-8aec-14aa675caae0/dynamically-obtain-mapping-info). – nmclean

1

Je pense que j'ai mal compris votre question la première fois. Avez-vous examiné le schéma edmx pour des indices?

Selon ce lien: http://msdn.microsoft.com/en-us/library/cc982042.aspx

Le schéma pour les applications qui ciblent la version .NET Framework 4 est défini dans le fichier Microsoft.Data.Entity.Design.Edmx_2.xsd . Le schéma pour les applications qui cible le .NET Framework version 3.5 SP1 est défini dans le fichier Microsoft.Data.Entity.Design.Edmx_1.xsd .

Ce sont en% VS100COMNTOOLS% \ .. \ .. \ Xml \ Schemas \ pour VS 2010, et% VS90COMNTOOLS% \ .. \ .. \ Xml \ Schemas \ (le 3.5 uniquement) pour VS 2008

0

Vous pouvez l'installer via NuGet dans Visual Studio et il sert toutes les métadonnées de vos fichiers EDMX que Microsoft se cache de vous, très simple, fonctionne très bien. Vous voulez accéder à toutes ces informations de stockage de bas niveau comme les types SQL de votre propriété, le schéma, tout y est. Vous pouvez même utiliser l'application Sample Windows.Forms dans le référentiel github pour définir un point d'arrêt et examiner les données.

0

Je travaille avec EF6 et je voulais ajouter un commentaire de synthèse aux classes générées par le template t4. Après avoir piraté pendant un moment, j'ai réussi à le faire en chargeant le fichier EDMX et en utilisant XPath pour trouver ce dont j'avais besoin.

var xmlContent = XDocument.Load(textTransform.Host.ResolvePath(inputFile)); 
var edmxNavigator = xmlContent.CreateNavigator(); 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(edmxNavigator.NameTable); 
nsMgr.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2009/11/edmx"); 
nsMgr.AddNamespace("store", "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"); 
nsMgr.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/11/edm/ssdl"); 
nsMgr.AddNamespace("cs", "http://schemas.microsoft.com/ado/2009/11/mapping/cs"); 
//This is the loop that came with the default template 
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection)) 
{ 
    fileManager.StartNewFile(entity.Name + ".cs"); 
    BeginNamespace(code); 

    var mappingAttribute = edmxNavigator.SelectSingleNode("/edmx:Edmx/edmx:Runtime/edmx:Mappings/cs:Mapping/cs:EntityContainerMapping/cs:EntitySetMapping/cs:EntityTypeMapping[@TypeName=\"" + entity.FullName + "\"]/cs:MappingFragment/@StoreEntitySet", nsMgr); 
    var entitySet = edmxNavigator.SelectSingleNode("/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema/ssdl:EntityContainer/ssdl:EntitySet[@Name=\"" + mappingAttribute.Value + "\"]", nsMgr); 
    var actualTableName = (entitySet.SelectSingleNode("@Table") ?? entitySet.SelectSingleNode("@Name")).Value; 
    var actualSchemaName = (entitySet.SelectSingleNode("@Schema", nsMgr) ?? entitySet.SelectSingleNode("@store:Schema", nsMgr)).Value; 

#> 

<#=codeStringGenerator.UsingDirectives(inHeader: false)#> 

/// <summary> 
/// Database Object: <#=actualSchemaName#>.<#=actualTableName#> 
/// </summary> 
<#=codeStringGenerator.EntityClassOpening(entity)#> 
Questions connexes