public MetadataLoadResult LoadMetadata(string inputFile)
        {
            var  loader = new MetadataLoader(this);
            bool loaded = false;
            EdmItemCollection   edmItemCollection   = loader.CreateEdmItemCollection(inputFile);
            StoreItemCollection storeItemCollection = null;

            if (loader.TryCreateStoreItemCollection(inputFile, out storeItemCollection))
            {
                StorageMappingItemCollection storageMappingItemCollection;
                if (loader.TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection))
                {
                    loaded = true;
                }
            }

            if (loaded == false)
            {
                throw new Exception("Cannot load a metadata from the file " + inputFile);
            }

            var mappingMetadata = LoadMappingMetadata(inputFile);
            var mappingNode     = mappingMetadata.Item1;
            var nsmgr           = mappingMetadata.Item2;

            var allEntitySets = storeItemCollection.GetAllEntitySets();

            return(new MetadataLoadResult
            {
                EdmItems = edmItemCollection,
                PropertyToColumnMapping = BuildEntityMappings(mappingNode, nsmgr, edmItemCollection.GetItems <EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets),
                ManyToManyMappings = BuildManyToManyMappings(mappingNode, nsmgr, edmItemCollection.GetAllAssociationSets(), allEntitySets),
                TphMappings = BuildTPHMappings(mappingNode, nsmgr, edmItemCollection.GetItems <EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets)
            });
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            Console.WriteLine("Entity Frameworks CodeGenerationTools Demo Program.\n");

            //I had problems with accessing Dictionary by [] index, so quickly used these
            //to check in normal C# usage.
            //var tc = new TestCollections();
            //tc.TestCollections2();

            try
            {
                //As this program only reads and interprets the XML within the EDMX,
                //there is no need for a ConnectionString in the App.Config and
                //no connection is made to a database.

                //Since this is a test program, let's assume you are executing from .\bin\Debug
                var currentdirectory = Environment.CurrentDirectory;
                var inputFile        = @"..\..\Model1.edmx";
                inputFile = Path.Combine(currentdirectory, inputFile);

                //Demo 1
                //EFFluentUtility is from
                //http://visualstudiogallery.msdn.microsoft.com/5d663b99-ed3b-481d-b7bc-b947d2457e3c
                //By opening the VSIX (DbContextFluentTemplate_V50, which is a ZIP) I've taken a
                //copy of "CSharpDbContextFluent.Mapping.tt" from the ItemTemplate.
                //Then copied the supporting classes from the template and
                //entered here in the CodeGenerationToolsLibrary project as a .Net Class here.
                //I've used the Mapping.tt because it is the most complex,
                //and shows how to obtain the Mapping info used to
                //create the EntityConfiguration from the EDMX.
                //
                // See PropertyToColumnMapping and ManyToManyMappings from
                // MetadataLoadResult
                //
                EF5FluentUtility   efu = new EF5FluentUtility();
                MetadataLoadResult mlr = efu.LoadMetadata(inputFile);

                var a = mlr.EdmItems;
                var b = mlr.ManyToManyMappings;
                var c = mlr.PropertyToColumnMapping;
                var d = mlr.TphMappings;

                //Obtain the EntityContainer from the ItemsCollection
                var container = mlr.EdmItems.GetItems <EntityContainer>()[0];

                //Iterate all the EntitySets and Properties
                //EntitySet are as in "People", where the EntityType is "Person"
                foreach (var entityset in container.BaseEntitySets.OfType <EntitySet>().OrderBy(e => e.Name))
                {
                    var entitysetname = entityset.Name;
                    var entityname    = entityset.ElementType.Name;
                    var entitytype    = entityset.ElementType;
                    var declaringtype = entityset.ElementType.NavigationProperties[0].DeclaringType;

                    //Navigation Properties for a particular Entity
                    var collectionNavigations1 = entityset.ElementType.NavigationProperties.Where(np => np.DeclaringType == entityset.ElementType);

                    // Find m:m relationshipsto configure for a particular Entity
                    var manyManyRelationships = entityset.ElementType.NavigationProperties
                                                .Where(np =>
                                                       //np.DeclaringType is EntityType &&
                                                       np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many &&
                                                       np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
                                                       // Ensures we only configure from one end.
                                                       // Convention is to have source on the left, as it would be diagrammatically.
                                                       && np.RelationshipType.RelationshipEndMembers.First() == np.FromEndMember)
                                                .ToArray();

                    //Now process the M:Ms
                    foreach (var navProperty in manyManyRelationships)
                    {
                        var otherNavProperty = navProperty.ToEndMember.GetEntityType().NavigationProperties.Where(n => n.RelationshipType == navProperty.RelationshipType && n != navProperty).Single();
                        var association      = (AssociationType)navProperty.RelationshipType;

                        //This did not work in the T4 Template.
                        var mapping1 = mlr.ManyToManyMappings[association];

                        var mapping2 = mlr.ManyToManyMappings.Where(m => m.Key.Name == association.Name).FirstOrDefault().Value;
                        var item1    = mapping1.Item1;

                        //This did not work in the T4 Template.
                        var leftKeyMappings1 = mapping1.Item2[navProperty.ToEndMember];
                        var leftKeyMappings2 = mapping1.Item2.Where(np => np.Key.Name == navProperty.ToEndMember.Name).FirstOrDefault().Value;

                        // Need to ensure that FKs are declared in the same order as the PK properties on each principal type
                        var leftType  = (EntityType)navProperty.DeclaringType;
                        var rightType = (EntityType)otherNavProperty.DeclaringType;

                        //Access using Index [navProperty.FromEndMember] did not work within template.
                        var leftKeyMappings  = mapping1.Item2.Where(np => np.Key.Name == navProperty.FromEndMember.Name).FirstOrDefault().Value;      //[navProperty.FromEndMember];
                        var rightKeyMappings = mapping1.Item2.Where(np => np.Key.Name == otherNavProperty.FromEndMember.Name).FirstOrDefault().Value; //[otherNavProperty.FromEndMember];

                        var left  = leftKeyMappings.Where(km => km.Key.Name == "PersonID");
                        var right = rightType.KeyMembers.Select(m => "\"" + rightKeyMappings.Where(km => km.Key.Name == m.Name).FirstOrDefault().Value + "\"").FirstOrDefault();
                    }

                    //Dual OrderBy to bring Keys to top of list
                    //Iterate all properties for this particular Entity.
                    var properties = entityset.ElementType.Properties.OrderBy(s => s.Name).OrderBy(p => entityset.ElementType.KeyMembers.Contains(p) == false).ToArray();
                    foreach (var property in properties)
                    {
                        var propertyname = property.Name;

                        //This did not work in the T4 Template.
                        var mapping1 = mlr.PropertyToColumnMapping[entityset.ElementType];

                        //PropertyToColumnMapping is a collection for ALL Entities, so here the particular Entity needs to be filtered out.
                        //Mapping returned is a complex generic Dictionary.
                        var mapping2 = mlr.PropertyToColumnMapping.Where(k => k.Key == entityset.ElementType).FirstOrDefault().Value;
                        var mapping3 = mlr.PropertyToColumnMapping.Where(k => k.Key.FullName == entityset.ElementType.FullName).FirstOrDefault().Value;

                        var mapping4 = mapping3.Item2.Where(p => p.Key.Name == property.Name).FirstOrDefault().Value;

                        var i1       = mapping1.Item1;
                        var i2       = mapping1.Item2;
                        var mapright = i2[property];
                    }
                }

                //********************************************************************************

                //Demo 2
                //This takes EF.Utility.CS.ttinclude and receates as
                //.net Classes.
                //
                MyTextTransformation tt   = new MyTextTransformation();
                CodeGenerationTools  code = new CodeGenerationTools(tt);

                CodeRegion     cregion = new CodeRegion(tt, 1);
                MetadataTools  mtool   = new MetadataTools(tt);
                MetadataLoader mloader = new MetadataLoader(tt);

                var ItemCollection = mloader.CreateEdmItemCollection(inputFile);

                var Container = ItemCollection.GetItems <EntityContainer>()[0];
                Console.WriteLine(String.Format("Container Name: {0}", Container.Name));
                Console.WriteLine(String.Format("Model Namespace: {0}", mloader.GetModelNamespace(inputFile)));
                Console.WriteLine(String.Format("No Of Items in ItemsCollection: {0}\n", ItemCollection.Count));
                Console.WriteLine("Press any key to continue.\n"); Console.ReadKey();

                foreach (var i in ItemCollection)
                {
                    Console.WriteLine(String.Format("Item: {0}, {1}", i.ToString(), i.BuiltInTypeKind.ToString()));
                }
                Console.WriteLine("Press any key to continue.\n"); Console.ReadKey();

                EdmItemCollection edmItemCollection = null;;
                var ret = mloader.TryCreateEdmItemCollection(inputFile, out edmItemCollection);

                StoreItemCollection storeItemCollection = null;
                ret = mloader.TryCreateStoreItemCollection(inputFile, out storeItemCollection);

                StorageMappingItemCollection storageMappingItemCollection = null;
                ret = mloader.TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection);
                foreach (var i in storageMappingItemCollection)
                {
                    Console.WriteLine(String.Format("Item: {0}, {1}", i.ToString(), i.BuiltInTypeKind.ToString()));
                }
                DataSpace ds = storageMappingItemCollection.DataSpace;

                MetadataWorkspace metadataWorkspace = null;
                ret = mloader.TryLoadAllMetadata(inputFile, out metadataWorkspace);

                //Get the schema "dbo" from a particular Entity.
                EntityContainer ec          = storeItemCollection.GetItems <EntityContainer>().First();
                EntitySet       eset        = ec.GetEntitySetByName(code.Escape("People"), true);
                string          schemaName1 = eset.MetadataProperties["Schema"].Value.ToString();

                //Get the schema "dbo" from any Entity. I guess the schema will be same for all?!
                EntitySetBase fes         = ec.BaseEntitySets.FirstOrDefault();
                string        schemaName2 = fes.MetadataProperties["Schema"].Value.ToString();

                var edmxSchema = EDMXchema.GetSchemaElement(inputFile);

                Console.WriteLine("Press any key to continue.\n"); Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("Press any key to quit.");
            Console.ReadKey();

            // var loadResult = LoadMetadata(inputFile);
        }