Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Importing EF Power Tools project.

  • Loading branch information...
commit 8e544cfe54db15517babd5951918a3582803a762 1 parent d0c4829
@bricelam bricelam authored
Showing with 4,912 additions and 0 deletions.
  1. +31 −0 PowerTools.sln
  2. +1 −0  packages/repositories.config
  3. +47 −0 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Context.tt
  4. +63 −0 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Entity.tt
  5. +268 −0 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Mapping.tt
  6. +527 −0 src/PowerTools/DbContextPackage.cs
  7. +235 −0 src/PowerTools/DbContextPackage.vsct
  8. +22 −0 src/PowerTools/Extensions/CompilerErrorCollectionExtensions.cs
  9. +58 −0 src/PowerTools/Extensions/CompilerErrorException.cs
  10. +58 −0 src/PowerTools/Extensions/EdmSchemaErrorException.cs
  11. +19 −0 src/PowerTools/Extensions/IComponentModelExtensions.cs
  12. +27 −0 src/PowerTools/Extensions/IEnumerableOfEdmSchemaErrorExtensions.cs
  13. +158 −0 src/PowerTools/Extensions/ProjectExtensions.cs
  14. +21 −0 src/PowerTools/Extensions/ProjectItemsExtensions.cs
  15. +21 −0 src/PowerTools/Extensions/SourceControlExtenstions.cs
  16. +12 −0 src/PowerTools/Extensions/StringExtensions.cs
  17. +29 −0 src/PowerTools/Extensions/XContainerExtensions.cs
  18. +11 −0 src/PowerTools/GlobalSuppressions.cs
  19. +14 −0 src/PowerTools/Guids.cs
  20. +51 −0 src/PowerTools/Handlers/AddCustomTemplatesHandler.cs
  21. +140 −0 src/PowerTools/Handlers/OptimizeContextHandler.cs
  22. +364 −0 src/PowerTools/Handlers/ReverseEngineerCodeFirstHandler.cs
  23. +72 −0 src/PowerTools/Handlers/ViewContextHandler.cs
  24. +48 −0 src/PowerTools/Handlers/ViewDdlHandler.cs
  25. BIN  src/PowerTools/License.rtf
  26. +14 −0 src/PowerTools/PkgCmdID.cs
  27. +261 −0 src/PowerTools/PowerTools.csproj
  28. +36 −0 src/PowerTools/Properties/AssemblyInfo.cs
  29. +10 −0 src/PowerTools/Properties/InternalsVisibleTo.cs
  30. +427 −0 src/PowerTools/Properties/Resources.cs
  31. +208 −0 src/PowerTools/Properties/Resources.resx
  32. +234 −0 src/PowerTools/Properties/Resources.tt
  33. BIN  src/PowerTools/Resources/1.png
  34. BIN  src/PowerTools/Resources/2.png
  35. BIN  src/PowerTools/Resources/3.png
  36. BIN  src/PowerTools/Resources/4.png
  37. BIN  src/PowerTools/Resources/5.png
  38. BIN  src/PowerTools/Resources/Package.ico
  39. +148 −0 src/PowerTools/Utilities/EdmxUtility.cs
  40. +192 −0 src/PowerTools/Utilities/EfTextTemplateHost.cs
  41. +11 −0 src/PowerTools/Utilities/FileExtensions.cs
  42. +44 −0 src/PowerTools/Utilities/RuntimeFailureMethods.cs
  43. +94 −0 src/PowerTools/Utilities/TemplateProcessor.cs
  44. +27 −0 src/PowerTools/Utilities/Templates.cs
  45. +136 −0 src/PowerTools/VSPackage.resx
  46. BIN  src/PowerTools/db.png
  47. BIN  src/PowerTools/menu.png
  48. +42 −0 src/PowerTools/source.extension.vsixmanifest
  49. +36 −0 test/PowerTools.Test/Extensions/CompilerErrorCollectionExtensionsTests.cs
  50. +54 −0 test/PowerTools.Test/Extensions/CompilerErrorExceptionTests.cs
  51. +54 −0 test/PowerTools.Test/Extensions/EdmSchemaErrorExceptionTests.cs
  52. +20 −0 test/PowerTools.Test/Extensions/IComponentModelExtensionsTests.cs
  53. +17 −0 test/PowerTools.Test/Extensions/StringExtensionsTests.cs
  54. +46 −0 test/PowerTools.Test/Extensions/XContainerExtensionsTests.cs
  55. +83 −0 test/PowerTools.Test/PowerTools.Test.csproj
  56. +36 −0 test/PowerTools.Test/Properties/AssemblyInfo.cs
  57. +210 −0 test/PowerTools.Test/Utilities/EdmxUtilityTests.cs
  58. +149 −0 test/PowerTools.Test/Utilities/EfTextTemplateHostTests.cs
  59. +21 −0 test/PowerTools.Test/Utilities/TemplatesTests.cs
  60. +5 −0 test/PowerTools.Test/packages.config
View
31 PowerTools.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 11
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2AE1B177-580C-44F1-9514-B3F23F4B1433}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerTools", "src\PowerTools\PowerTools.csproj", "{16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerTools.Test", "test\PowerTools.Test\PowerTools.Test.csproj", "{ADCD3A3D-2564-48F3-81A9-B0B532675808}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ADCD3A3D-2564-48F3-81A9-B0B532675808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ADCD3A3D-2564-48F3-81A9-B0B532675808}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ADCD3A3D-2564-48F3-81A9-B0B532675808}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ADCD3A3D-2564-48F3-81A9-B0B532675808}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {ADCD3A3D-2564-48F3-81A9-B0B532675808} = {2AE1B177-580C-44F1-9514-B3F23F4B1433}
+ EndGlobalSection
+EndGlobal
View
1  packages/repositories.config
@@ -3,4 +3,5 @@
<repository path="..\test\EntityFramework\FunctionalTests\packages.config" />
<repository path="..\test\EntityFramework\UnitTests\packages.config" />
<repository path="..\test\EntityFramework\VBTests\packages.config" />
+ <repository path="..\test\PowerTools.Test\packages.config" />
</repositories>
View
47 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Context.tt
@@ -0,0 +1,47 @@
+<#@ template hostspecific="true" language="C#" #>
+<#@ include file="EF.Utility.CS.ttinclude" #><#@
+ output extension=".cs" #><#
+
+ var efHost = (EfTextTemplateHost)Host;
+ var code = new CodeGenerationTools(this);
+#>
+using System.Data.Entity;
+using System.Data.Entity.Infrastructure;
+using <#= code.EscapeNamespace(efHost.MappingNamespace) #>;
+
+namespace <#= code.EscapeNamespace(efHost.Namespace) #>
+{
+ public class <#= efHost.EntityContainer.Name #> : DbContext
+ {
+ static <#= efHost.EntityContainer.Name #>()
+ {
+ Database.SetInitializer<<#= efHost.EntityContainer.Name #>>(null);
+ }
+
+ public <#= efHost.EntityContainer.Name #>()
+ : base("Name=<#= efHost.EntityContainer.Name #>")
+ {
+ }
+
+<#
+ foreach (var set in efHost.EntityContainer.BaseEntitySets.OfType<EntitySet>())
+ {
+#>
+ public DbSet<<#= set.ElementType.Name #>> <#= set.Name #> { get; set; }
+<#
+ }
+#>
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+<#
+ foreach (var set in efHost.EntityContainer.BaseEntitySets.OfType<EntitySet>())
+ {
+#>
+ modelBuilder.Configurations.Add(new <#= set.ElementType.Name #>Map());
+<#
+ }
+#>
+ }
+ }
+}
View
63 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Entity.tt
@@ -0,0 +1,63 @@
+<#@ template hostspecific="true" language="C#" #>
+<#@ include file="EF.Utility.CS.ttinclude" #><#@
+ output extension=".cs" #><#
+
+ var efHost = (EfTextTemplateHost)Host;
+ var code = new CodeGenerationTools(this);
+#>
+using System;
+using System.Collections.Generic;
+
+namespace <#= code.EscapeNamespace(efHost.Namespace) #>
+{
+ public class <#= efHost.EntityType.Name #>
+ {
+<#
+ var collectionNavigations = efHost.EntityType.NavigationProperties.Where(
+ np => np.DeclaringType == efHost.EntityType
+ && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
+
+ // Add a ctor to initialize any collections
+ if (collectionNavigations.Any())
+ {
+#>
+ public <#= code.Escape(efHost.EntityType) #>()
+ {
+<#
+ foreach (var navProperty in collectionNavigations)
+ {
+#>
+ this.<#= code.Escape(navProperty) #> = new List<<#= code.Escape(navProperty.ToEndMember.GetEntityType()) #>>();
+<#
+ }
+#>
+ }
+
+<#
+ }
+
+ foreach (var property in efHost.EntityType.Properties)
+ {
+#>
+ <#= Accessibility.ForProperty(property) #> <#= code.Escape(property.TypeUsage) #> <#= code.Escape(property) #> { get; set; }
+<#
+ }
+
+ foreach (var navProperty in efHost.EntityType.NavigationProperties.Where(np => np.DeclaringType == efHost.EntityType))
+ {
+ if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
+ {
+#>
+ public virtual ICollection<<#= code.Escape(navProperty.ToEndMember.GetEntityType()) #>> <#= code.Escape(navProperty) #> { get; set; }
+<#
+ }
+ else
+ {
+#>
+ public virtual <#= code.Escape(navProperty.ToEndMember.GetEntityType()) #> <#= code.Escape(navProperty) #> { get; set; }
+<#
+ }
+ }
+#>
+ }
+}
View
268 src/PowerTools/CodeTemplates/ReverseEngineerCodeFirst/Mapping.tt
@@ -0,0 +1,268 @@
+<#
+// Simplifying assumptions based on reverse engineer rules
+// - No complex types
+// - One entity container
+// - No inheritance
+// - Always have two navigation properties
+// - All associations expose FKs (except many:many)
+#>
+<#@ template hostspecific="true" language="C#" #>
+<#@ include file="EF.Utility.CS.ttinclude" #><#@
+ output extension=".cs" #><#
+
+ var efHost = (EfTextTemplateHost)Host;
+ var code = new CodeGenerationTools(this);
+
+ if (efHost.EntityFrameworkVersion >= new Version(4, 4))
+ {
+#>
+using System.ComponentModel.DataAnnotations.Schema;
+<#
+ }
+ else
+ {
+#>
+using System.ComponentModel.DataAnnotations;
+<#
+ }
+#>
+using System.Data.Entity.ModelConfiguration;
+
+namespace <#= code.EscapeNamespace(efHost.Namespace) #>
+{
+ public class <#= efHost.EntityType.Name #>Map : EntityTypeConfiguration<<#= efHost.EntityType.Name #>>
+ {
+ public <#= efHost.EntityType.Name #>Map()
+ {
+ // Primary Key
+<#
+ if (efHost.EntityType.KeyMembers.Count() == 1)
+ {
+#>
+ this.HasKey(t => t.<#= efHost.EntityType.KeyMembers.Single().Name #>);
+<#
+ }
+ else
+ {
+#>
+ this.HasKey(t => new { <#= string.Join(", ", efHost.EntityType.KeyMembers.Select(m => "t." + m.Name)) #> });
+<#
+ }
+#>
+
+ // Properties
+<#
+ foreach (var prop in efHost.EntityType.Properties)
+ {
+ var type = (PrimitiveType)prop.TypeUsage.EdmType;
+ var isKey = efHost.EntityType.KeyMembers.Contains(prop);
+ var storeProp = efHost.PropertyToColumnMappings[prop];
+ var sgpFacet = storeProp.TypeUsage.Facets.SingleOrDefault(f => f.Name == "StoreGeneratedPattern");
+ var storeGeneratedPattern = sgpFacet == null
+ ? StoreGeneratedPattern.None
+ : (StoreGeneratedPattern)sgpFacet.Value;
+
+ var configLines = new List<string>();
+
+ if (type.ClrEquivalentType == typeof(int)
+ || type.ClrEquivalentType == typeof(decimal)
+ || type.ClrEquivalentType == typeof(short)
+ || type.ClrEquivalentType == typeof(long))
+ {
+ if (isKey && storeGeneratedPattern != StoreGeneratedPattern.Identity)
+ {
+ configLines.Add(".HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)");
+ }
+ else if ((!isKey || efHost.EntityType.KeyMembers.Count > 1) && storeGeneratedPattern == StoreGeneratedPattern.Identity)
+ {
+ configLines.Add(".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)");
+ }
+ }
+
+ if (type.ClrEquivalentType == typeof(string)
+ || type.ClrEquivalentType == typeof(byte[]))
+ {
+ if (!prop.Nullable)
+ {
+ configLines.Add(".IsRequired()");
+ }
+
+ var unicodeFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "IsUnicode");
+ if(unicodeFacet != null && !(bool)unicodeFacet.Value)
+ {
+ configLines.Add(".IsUnicode(false)");
+ }
+
+ var fixedLengthFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "FixedLength");
+ if (fixedLengthFacet != null && (bool)fixedLengthFacet.Value)
+ {
+ configLines.Add(".IsFixedLength()");
+ }
+
+ var maxLengthFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength");
+ if (maxLengthFacet != null && !maxLengthFacet.IsUnbounded)
+ {
+ configLines.Add(string.Format(".HasMaxLength({0})", maxLengthFacet.Value));
+
+ if (storeGeneratedPattern == StoreGeneratedPattern.Computed
+ && type.ClrEquivalentType == typeof(byte[])
+ && (int)maxLengthFacet.Value == 8)
+ {
+ configLines.Add(".IsRowVersion()");
+ }
+ }
+ }
+
+ if(configLines.Any())
+ {
+#>
+ this.Property(t => t.<#= prop.Name #>)
+ <#= string.Join("\r\n ", configLines) #>;
+
+<#
+ }
+ }
+
+ var tableSet = efHost.TableSet;
+ var tableName = (string)tableSet.MetadataProperties["Table"].Value
+ ?? tableSet.Name;
+ var schemaName = (string)tableSet.MetadataProperties["Schema"].Value;
+#>
+ // Table & Column Mappings
+<#
+ if (schemaName == "dbo" || string.IsNullOrWhiteSpace(schemaName))
+ {
+#>
+ this.ToTable("<#= tableName #>");
+<#
+ }
+ else
+ {
+#>
+ this.ToTable("<#= tableName #>", "<#= schemaName #>");
+<#
+ }
+
+ foreach (var property in efHost.EntityType.Properties)
+ {
+#>
+ this.Property(t => t.<#= property.Name #>).HasColumnName("<#= efHost.PropertyToColumnMappings[property].Name #>");
+<#
+ }
+
+ // Find m:m relationshipsto configure
+ var manyManyRelationships = efHost.EntityType.NavigationProperties
+ .Where(np => np.DeclaringType == efHost.EntityType
+ && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
+ && np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
+ && np.RelationshipType.RelationshipEndMembers.First() == np.FromEndMember); // <- ensures we only configure from one end
+
+ // Find FK relationships that this entity is the dependent of
+ var fkRelationships = efHost.EntityType.NavigationProperties
+ .Where(np => np.DeclaringType == efHost.EntityType
+ && ((AssociationType)np.RelationshipType).IsForeignKey
+ && ((AssociationType)np.RelationshipType).ReferentialConstraints.Single().ToRole == np.FromEndMember);
+
+ if(manyManyRelationships.Any() || fkRelationships.Any())
+ {
+#>
+
+ // Relationships
+<#
+ 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;
+ var mapping = efHost.ManyToManyMappings[association];
+ var item1 = mapping.Item1;
+ var mappingTableName = (string)mapping.Item1.MetadataProperties["Table"].Value
+ ?? item1.Name;
+ var mappingSchemaName = (string)item1.MetadataProperties["Schema"].Value;
+
+ // Need to ensure that FKs are decalred in the same order as the PK properties on each principal type
+ var leftType = (EntityType)navProperty.DeclaringType;
+ var leftKeyMappings = mapping.Item2[navProperty.FromEndMember];
+ var leftColumns = string.Join(", ", leftType.KeyMembers.Select(m => "\"" + leftKeyMappings[m] + "\""));
+ var rightType = (EntityType)otherNavProperty.DeclaringType;
+ var rightKeyMappings = mapping.Item2[otherNavProperty.FromEndMember];
+ var rightColumns = string.Join(", ", rightType.KeyMembers.Select(m => "\"" + rightKeyMappings[m] + "\""));
+#>
+ this.HasMany(t => t.<#= code.Escape(navProperty) #>)
+ .WithMany(t => t.<#= code.Escape(otherNavProperty) #>)
+ .Map(m =>
+ {
+<#
+ if (mappingSchemaName == "dbo" || string.IsNullOrWhiteSpace(mappingSchemaName))
+ {
+#>
+ m.ToTable("<#= mappingTableName #>");
+<#
+ }
+ else
+ {
+#>
+ m.ToTable("<#= mappingTableName #>", "<#= mappingSchemaName #>");
+<#
+ }
+#>
+ m.MapLeftKey(<#= leftColumns #>);
+ m.MapRightKey(<#= rightColumns #>);
+ });
+
+<#
+ }
+
+ foreach (var navProperty in fkRelationships)
+ {
+ var otherNavProperty = navProperty.ToEndMember.GetEntityType().NavigationProperties.Where(n => n.RelationshipType == navProperty.RelationshipType && n != navProperty).Single();
+ var association = (AssociationType)navProperty.RelationshipType;
+
+ if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
+ {
+#>
+ this.HasRequired(t => t.<#= code.Escape(navProperty) #>)
+<#
+ }
+ else
+ {
+#>
+ this.HasOptional(t => t.<#= code.Escape(navProperty) #>)
+<#
+ }
+
+ if(navProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
+ {
+#>
+ .WithMany(t => t.<#= code.Escape(otherNavProperty) #>)
+<#
+ if(association.ReferentialConstraints.Single().ToProperties.Count == 1)
+ {
+#>
+ .HasForeignKey(d => d.<#= association.ReferentialConstraints.Single().ToProperties.Single().Name #>);
+<#
+ }
+ else
+ {
+#>
+ .HasForeignKey(d => new { <#= string.Join(", ", association.ReferentialConstraints.Single().ToProperties.Select(p => "d." + p.Name)) #> });
+<#
+ }
+ }
+ else
+ {
+ // NOTE: We can assume that this is a required:optional relationship
+ // as EDMGen will never create an optional:optional relationship
+ // because everything is one:many except PK-PK relationships which must be required
+#>
+ .WithOptional(t => t.<#= code.Escape(otherNavProperty) #>);
+<#
+ }
+ }
+#>
+
+<#
+ }
+#>
+ }
+ }
+}
View
527 src/PowerTools/DbContextPackage.cs
@@ -0,0 +1,527 @@
+namespace Microsoft.DbContextPackage
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel.Design;
+ using System.Configuration;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+ using System.Runtime.InteropServices;
+ using EnvDTE;
+ using EnvDTE80;
+ using Microsoft.DbContextPackage.Extensions;
+ using Microsoft.DbContextPackage.Handlers;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+ using Microsoft.VisualStudio.Shell;
+ using Microsoft.VisualStudio.Shell.Design;
+ using Microsoft.VisualStudio.Shell.Interop;
+ using Configuration = System.Configuration.Configuration;
+ using ConfigurationManager = System.Configuration.ConfigurationManager;
+
+ [PackageRegistration(UseManagedResourcesOnly = true)]
+ [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
+ [ProvideMenuResource("Menus.ctmenu", 1)]
+ [Guid(GuidList.guidDbContextPackagePkgString)]
+ [ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
+ public sealed class DbContextPackage : Package
+ {
+ private readonly AddCustomTemplatesHandler _addCustomTemplatesHandler;
+ private readonly OptimizeContextHandler _optimizeContextHandler;
+ private readonly ReverseEngineerCodeFirstHandler _reverseEngineerCodeFirstHandler;
+ private readonly ViewContextHandler _viewContextHandler;
+ private readonly ViewDdlHandler _viewDdlHandler;
+
+ private DTE2 _dte2;
+
+ public DbContextPackage()
+ {
+ _addCustomTemplatesHandler = new AddCustomTemplatesHandler(this);
+ _optimizeContextHandler = new OptimizeContextHandler(this);
+ _reverseEngineerCodeFirstHandler = new ReverseEngineerCodeFirstHandler(this);
+ _viewContextHandler = new ViewContextHandler(this);
+ _viewDdlHandler = new ViewDdlHandler(this);
+ }
+
+ internal DTE2 DTE2
+ {
+ get { return _dte2; }
+ }
+
+ protected override void Initialize()
+ {
+ base.Initialize();
+
+ _dte2 = GetService(typeof(DTE)) as DTE2;
+
+ if (_dte2 == null)
+ {
+ return;
+ }
+
+ var oleMenuCommandService
+ = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
+
+ if (oleMenuCommandService != null)
+ {
+ var menuCommandID1 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidViewEntityDataModel);
+ var menuItem1 = new OleMenuCommand(OnItemContextMenuInvokeHandler, null, OnItemMenuBeforeQueryStatus, menuCommandID1);
+
+ oleMenuCommandService.AddCommand(menuItem1);
+
+ var menuCommandID2 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidViewEntityDataModelXml);
+ var menuItem2 = new OleMenuCommand(OnItemContextMenuInvokeHandler, null, OnItemMenuBeforeQueryStatus, menuCommandID2);
+
+ oleMenuCommandService.AddCommand(menuItem2);
+
+ var menuCommandID3 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidPrecompileEntityDataModelViews);
+ var menuItem3 = new OleMenuCommand(OnOptimizeContextInvokeHandler, null, OnOptimizeContextBeforeQueryStatus, menuCommandID3);
+
+ oleMenuCommandService.AddCommand(menuItem3);
+
+ var menuCommandID4 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidViewEntityModelDdl);
+ var menuItem4 = new OleMenuCommand(OnItemContextMenuInvokeHandler, null, OnItemMenuBeforeQueryStatus, menuCommandID4);
+
+ oleMenuCommandService.AddCommand(menuItem4);
+
+ var menuCommandID5 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidReverseEngineerCodeFirst);
+ var menuItem5 = new OleMenuCommand(OnProjectContextMenuInvokeHandler, null, OnProjectMenuBeforeQueryStatus, menuCommandID5);
+
+ oleMenuCommandService.AddCommand(menuItem5);
+
+ var menuCommandID6 = new CommandID(GuidList.guidDbContextPackageCmdSet, (int)PkgCmdIDList.cmdidCustomizeReverseEngineerTemplates);
+ var menuItem6 = new OleMenuCommand(OnProjectContextMenuInvokeHandler, null, OnProjectMenuBeforeQueryStatus, menuCommandID6);
+
+ oleMenuCommandService.AddCommand(menuItem6);
+ }
+ }
+
+ private void OnProjectMenuBeforeQueryStatus(object sender, EventArgs e)
+ {
+ var menuCommand = sender as MenuCommand;
+
+ if (menuCommand == null)
+ {
+ return;
+ }
+
+ if (_dte2.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ var project = _dte2.SelectedItems.Item(1).Project;
+
+ if (project == null)
+ {
+ return;
+ }
+
+ menuCommand.Visible =
+ project.Kind == "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; // csproj
+ }
+
+ private void OnItemMenuBeforeQueryStatus(object sender, EventArgs e)
+ {
+ OnItemMenuBeforeQueryStatus(
+ sender,
+ new[] { FileExtensions.CSharp, FileExtensions.VisualBasic });
+ }
+
+ private void OnOptimizeContextBeforeQueryStatus(object sender, EventArgs e)
+ {
+ OnItemMenuBeforeQueryStatus(
+ sender,
+ new[] { FileExtensions.CSharp, FileExtensions.VisualBasic, FileExtensions.EntityDataModel });
+ }
+
+ private void OnItemMenuBeforeQueryStatus(object sender, IEnumerable<string> supportedExtensions)
+ {
+ Contract.Requires(supportedExtensions != null);
+
+ var menuCommand = sender as MenuCommand;
+
+ if (menuCommand == null)
+ {
+ return;
+ }
+
+ if (_dte2.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ var extensionValue = GetSelectedItemExtension();
+ menuCommand.Visible = supportedExtensions.Contains(extensionValue);
+ }
+
+ private string GetSelectedItemExtension()
+ {
+ var selectedItem = _dte2.SelectedItems.Item(1);
+
+ if ((selectedItem.ProjectItem == null)
+ || (selectedItem.ProjectItem.Properties == null))
+ {
+ return null;
+ }
+
+ var extension = selectedItem.ProjectItem.Properties.Item("Extension");
+
+ if (extension == null)
+ {
+ return null;
+ }
+
+ return (string)extension.Value;
+ }
+
+ private void OnProjectContextMenuInvokeHandler(object sender, EventArgs e)
+ {
+ var menuCommand = sender as MenuCommand;
+ if (menuCommand == null || _dte2.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ var project = _dte2.SelectedItems.Item(1).Project;
+ if (project == null)
+ {
+ return;
+ }
+
+ if (menuCommand.CommandID.ID == PkgCmdIDList.cmdidReverseEngineerCodeFirst)
+ {
+ _reverseEngineerCodeFirstHandler.ReverseEngineerCodeFirst(project);
+ }
+ else if (menuCommand.CommandID.ID == PkgCmdIDList.cmdidCustomizeReverseEngineerTemplates)
+ {
+ _addCustomTemplatesHandler.AddCustomTemplates(project);
+ }
+ }
+
+ private void OnItemContextMenuInvokeHandler(object sender, EventArgs e)
+ {
+ var menuCommand = sender as MenuCommand;
+
+ if (menuCommand == null)
+ {
+ return;
+ }
+
+ if (_dte2.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ Type systemContextType;
+ var context = DiscoverUserContextType(out systemContextType);
+
+ if (context != null)
+ {
+ if (menuCommand.CommandID.ID == PkgCmdIDList.cmdidPrecompileEntityDataModelViews)
+ {
+ _optimizeContextHandler.OptimizeContext(context);
+ }
+ else if (menuCommand.CommandID.ID == PkgCmdIDList.cmdidViewEntityModelDdl)
+ {
+ _viewDdlHandler.ViewDdl(context);
+ }
+ else
+ {
+ _viewContextHandler.ViewContext(menuCommand, context, systemContextType);
+ }
+ }
+ }
+
+ private void OnOptimizeContextInvokeHandler(object sender, EventArgs e)
+ {
+ if (_dte2.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ var extensionValue = GetSelectedItemExtension();
+
+ if (extensionValue != FileExtensions.EntityDataModel)
+ {
+ OnItemContextMenuInvokeHandler(sender, e);
+
+ return;
+ }
+
+ _optimizeContextHandler.OptimizeEdmx(
+ (string)_dte2.SelectedItems.Item(1).ProjectItem.Properties.Item("FullPath").Value);
+ }
+
+ internal static dynamic GetObjectContext(dynamic context)
+ {
+ var objectContextAdapterType
+ = context.GetType().GetInterface("System.Data.Entity.Infrastructure.IObjectContextAdapter");
+
+ return objectContextAdapterType.InvokeMember("ObjectContext", BindingFlags.GetProperty, null, context, null);
+ }
+
+ internal void LogError(string statusMessage, Exception exception)
+ {
+ Contract.Requires(!string.IsNullOrWhiteSpace(statusMessage));
+ Contract.Requires(exception != null);
+
+ var edmSchemaErrorException = exception as EdmSchemaErrorException;
+ var compilerErrorException = exception as CompilerErrorException;
+
+ _dte2.StatusBar.Text = statusMessage;
+
+ var buildOutputWindow = _dte2.ToolWindows.OutputWindow.OutputWindowPanes.Item("Build");
+
+ buildOutputWindow.OutputString(Environment.NewLine);
+
+ if (edmSchemaErrorException != null)
+ {
+ buildOutputWindow.OutputString(edmSchemaErrorException.Message + Environment.NewLine);
+
+ foreach (var error in edmSchemaErrorException.Errors)
+ {
+ buildOutputWindow.OutputString(error + Environment.NewLine);
+ }
+ }
+ else if (compilerErrorException != null)
+ {
+ buildOutputWindow.OutputString(compilerErrorException.Message + Environment.NewLine);
+
+ foreach (var error in compilerErrorException.Errors)
+ {
+ buildOutputWindow.OutputString(error + Environment.NewLine);
+ }
+ }
+ else
+ {
+ buildOutputWindow.OutputString(exception + Environment.NewLine);
+ }
+
+ buildOutputWindow.Activate();
+ }
+
+ private dynamic DiscoverUserContextType(out Type systemContextType)
+ {
+ var project = _dte2.SelectedItems.Item(1).ProjectItem.ContainingProject;
+
+ if (!project.TryBuild())
+ {
+ _dte2.StatusBar.Text = Strings.BuildFailed;
+ systemContextType = null;
+
+ return null;
+ }
+
+ DynamicTypeService typeService;
+ IVsSolution solution;
+ using (var serviceProvider = new ServiceProvider((VisualStudio.OLE.Interop.IServiceProvider)_dte2.DTE))
+ {
+ typeService = (DynamicTypeService)serviceProvider.GetService(typeof(DynamicTypeService));
+ solution = (IVsSolution)serviceProvider.GetService(typeof(SVsSolution));
+ }
+
+ IVsHierarchy vsHierarchy;
+ var hr = solution.GetProjectOfUniqueName(_dte2.SelectedItems.Item(1).ProjectItem.ContainingProject.UniqueName, out vsHierarchy);
+
+ if (hr != ProjectExtensions.S_OK)
+ {
+ throw Marshal.GetExceptionForHR(hr);
+ }
+
+ var resolver = typeService.GetTypeResolutionService(vsHierarchy);
+
+ systemContextType = resolver.GetType("System.Data.Entity.DbContext");
+
+ if (systemContextType != null)
+ {
+ var codeElements = FindClassesInCodeModel(_dte2.SelectedItems.Item(1).ProjectItem.FileCodeModel.CodeElements);
+
+ if (codeElements.Any())
+ {
+ var contextInfoType = systemContextType.Assembly.GetType("System.Data.Entity.Infrastructure.DbContextInfo");
+ var startUpProject = GetStartUpProject() ?? project;
+ Configuration userConfig;
+
+ try
+ {
+ userConfig = GetUserConfig(startUpProject);
+ }
+ catch (Exception ex)
+ {
+ LogError(Strings.LoadConfigFailed, ex);
+
+ return null;
+ }
+
+ SetDataDirectory(startUpProject);
+
+ foreach (var codeElement in codeElements)
+ {
+ var userContextType = resolver.GetType(codeElement.FullName);
+
+ if (userContextType != null && systemContextType.IsAssignableFrom(userContextType))
+ {
+ dynamic contextInfo;
+
+ if (contextInfoType != null)
+ {
+ var constructor = contextInfoType.GetConstructor(new[] { typeof(Type), typeof(Configuration) });
+
+ if (constructor != null)
+ {
+ // Versions 4.3.0 and higher
+ contextInfo = constructor.Invoke(new object[] { userContextType, userConfig });
+ }
+ else
+ {
+ constructor = contextInfoType.GetConstructor(new[] { typeof(Type), typeof(ConnectionStringSettingsCollection) });
+ Contract.Assert(constructor != null);
+
+ // Versions 4.1.10715 through 4.2.0.0
+ contextInfo = constructor.Invoke(new object[] { userContextType, userConfig.ConnectionStrings.ConnectionStrings });
+ }
+ }
+ else
+ {
+ // Versions 4.1.10331.0 and lower
+ throw Error.UnsupportedVersion();
+ }
+
+ if (contextInfo.IsConstructible)
+ {
+ DisableDatabaseInitializer(userContextType, systemContextType);
+
+ try
+ {
+ return contextInfo.CreateInstance();
+ }
+ catch (Exception exception)
+ {
+ LogError(Strings.CreateContextFailed(userContextType.Name), exception);
+
+ return null;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ _dte2.StatusBar.Text = Strings.NoContext;
+
+ return null;
+ }
+
+ private Project GetStartUpProject()
+ {
+ var startupProjectPaths = (object[])_dte2.Solution.SolutionBuild.StartupProjects;
+
+ if (startupProjectPaths.Length == 1)
+ {
+ var startupProjectPath = (string)startupProjectPaths[0];
+
+ if (!Path.IsPathRooted(startupProjectPath))
+ {
+ var solutionPath = Path.GetDirectoryName((string)_dte2.Solution.Properties.Item("Path").Value);
+ startupProjectPath = Path.Combine(
+ solutionPath,
+ startupProjectPath);
+ }
+
+ return _dte2.Solution.Projects.Cast<Project>().Single(
+ p =>
+ {
+ string fullName;
+ try
+ {
+ fullName = p.FullName;
+ }
+ catch (NotImplementedException)
+ {
+ return false;
+ }
+
+ return fullName == startupProjectPath;
+ });
+ }
+
+ return null;
+ }
+
+ private static Configuration GetUserConfig(Project project)
+ {
+ Contract.Requires(project != null);
+
+ var userConfigFilename
+ = Path.Combine(
+ (string)project.Properties.Item("FullPath").Value,
+ project.IsWebProject()
+ ? "Web.config"
+ : "App.config");
+
+ return ConfigurationManager.OpenMappedExeConfiguration(
+ new ExeConfigurationFileMap { ExeConfigFilename = userConfigFilename },
+ ConfigurationUserLevel.None);
+ }
+
+ private static void SetDataDirectory(Project project)
+ {
+ Contract.Requires(project != null);
+
+ AppDomain.CurrentDomain.SetData(
+ "DataDirectory",
+ project.IsWebProject()
+ ? Path.Combine(project.GetProjectDir(), "App_Data")
+ : project.GetTargetDir());
+ }
+
+ private static IEnumerable<CodeElement> FindClassesInCodeModel(CodeElements codeElements)
+ {
+ Contract.Requires(codeElements != null);
+
+ foreach (CodeElement codeElement in codeElements)
+ {
+ if (codeElement.Kind == vsCMElement.vsCMElementClass)
+ {
+ yield return codeElement;
+ }
+
+ foreach (var element in FindClassesInCodeModel(codeElement.Children))
+ {
+ yield return element;
+ }
+ }
+ }
+
+ private static void DisableDatabaseInitializer(Type userContextType, Type systemContextType)
+ {
+ Contract.Requires(userContextType != null);
+ Contract.Requires(systemContextType != null);
+
+ var databaseType = systemContextType.Assembly.GetType("System.Data.Entity.Database");
+
+ if (databaseType != null)
+ {
+ var setInitializerMethodInfo
+ = databaseType.GetMethod("SetInitializerInternal", BindingFlags.NonPublic | BindingFlags.Static);
+
+ if (setInitializerMethodInfo != null)
+ {
+ var boundSetInitializerMethodInfo
+ = setInitializerMethodInfo.MakeGenericMethod(userContextType);
+
+ boundSetInitializerMethodInfo.Invoke(null, new object[] { null, true });
+ }
+ }
+ }
+
+ internal T GetService<T>()
+ where T : class
+ {
+ return (T)GetService(typeof(T));
+ }
+ }
+}
View
235 src/PowerTools/DbContextPackage.vsct
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- This is the file that defines the actual layout and type of the commands.
+ It is divided in different sections (e.g. command definition, command
+ placement, ...), with each defining a specific set of properties.
+ See the comment before each section for more details about how to
+ use it. -->
+
+ <!-- The VSCT compiler (the tool that translates this file into the binary
+ format that VisualStudio will consume) has the ability to run a preprocessor
+ on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
+ it is possible to define includes and macros with the same syntax used
+ in C++ files. Using this ability of the compiler here, we include some files
+ defining some of the constants that we will use inside the file. -->
+
+ <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
+ <Extern href="stdidcmd.h" />
+
+ <!--This header contains the command ids for the menus provided by the shell. -->
+ <Extern href="vsshlids.h" />
+
+ <!--Definition of some VSCT specific constants. In this sample we use it for the IDs inside the guidOfficeIcon group. -->
+ <!--<Extern href="msobtnid.h" xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" />-->
+
+ <!--The Commands section is where we the commands, menus and menu groups are defined.
+ This section uses a Guid to identify the package that provides the command defined inside it. -->
+ <Commands package="guidDbContextPackagePkg">
+ <!-- Inside this section we have different sub-sections: one for the menus, another
+ for the menu groups, one for the buttons (the actual commands), one for the combos
+ and the last one for the bitmaps used. Each element is identified by a command id that
+ is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
+ called "command set" and is used to group different command inside a logically related
+ group; your package should define its own command set in order to avoid collisions
+ with command ids defined by other packages. -->
+
+
+ <!-- In this section you can define new menu groups. A menu group is a container for
+ other menus or buttons (commands); from a visual point of view you can see the
+ group as the part of a menu contained between two lines. The parent of a group
+ must be a menu. -->
+ <Groups>
+
+ <Group guid="guidDbContextPackageCmdSet" id="cmdidEdmMenuGroup" priority="0x0100">
+ <Parent guid="guidDbContextPackageCmdSet" id="IDM_VS_CTXT_ITEMNODE" />
+ </Group>
+
+ <Group guid="guidDbContextPackageCmdSet" id="cmdidEdmMenuItemsGroup" priority="0x0200">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmMenu" />
+ </Group>
+
+ <Group guid="guidDbContextPackageCmdSet" id="cmdidEdmViewMenuItemsGroup" priority="0x0100">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmMenu" />
+ </Group>
+
+ <Group guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuGroup" priority="0x0100">
+ <Parent guid="guidDbContextPackageCmdSet" id="IDM_VS_CTXT_PROJNODE" />
+ </Group>
+
+ <Group guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuItemsGroup" priority="0x0100">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenu" />
+ </Group>
+
+ </Groups>
+
+ <Menus>
+
+ <Menu guid="guidDbContextPackageCmdSet" id="cmdidEdmMenu" priority="0x0100" type="Menu">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmMenuGroup" />
+ <Strings>
+ <CommandName>Entity Framework</CommandName>
+ <ButtonText>Entity Framework</ButtonText>
+ </Strings>
+ </Menu>
+
+ <Menu guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenu" priority="0x0100" type="Menu">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuGroup" />
+ <Strings>
+ <CommandName>Entity Framework</CommandName>
+ <ButtonText>Entity Framework</ButtonText>
+ </Strings>
+ </Menu>
+
+ </Menus>
+
+ <!--Buttons section. -->
+ <!--This section defines the elements the user can interact with, like a menu command or a button
+ or combo box in a toolbar. -->
+ <Buttons>
+ <!--To define a menu group you have to specify its ID, the parent menu and its display priority.
+ The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
+ the CommandFlag node.
+ You can add more than one CommandFlag node e.g.:
+ <CommandFlag>DefaultInvisible</CommandFlag>
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ If you do not want an image next to your command, remove the Icon node or set it to <Icon guid="guidOfficeIcon" id="msotcidNoIcon" /> -->
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidViewEntityDataModel" priority="0x0100" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmViewMenuItemsGroup" />
+ <Icon guid="guidImage1" id="bmpPic1" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidViewEntityDataModel</CommandName>
+ <ButtonText>View Entity Data Model (Read-only)</ButtonText>
+ </Strings>
+ </Button>
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidViewEntityDataModelXml" priority="0x0100" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmViewMenuItemsGroup" />
+ <Icon guid="guidImage2" id="bmpPic2" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidViewEntityDataModelXml</CommandName>
+ <ButtonText>View Entity Data Model XML</ButtonText>
+ </Strings>
+ </Button>
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidPrecompileEntityDataModelViews" priority="0x0200" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmMenuItemsGroup" />
+ <Icon guid="guidImage3" id="bmpPic3" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidPrecompileEntityDataModelViews</CommandName>
+ <ButtonText>Generate Views</ButtonText>
+ </Strings>
+ </Button>
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidViewEntityModelDdl" priority="0x0100" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmViewMenuItemsGroup" />
+ <Icon guid="guidImage4" id="bmpPic4" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidViewEntityModelDdl</CommandName>
+ <ButtonText>View Entity Data Model DDL SQL</ButtonText>
+ </Strings>
+ </Button>
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidReverseEngineerCodeFirst" priority="0x0100" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuItemsGroup" />
+ <Icon guid="guidImage5" id="bmpPic5" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidReverseEngineerCodeFirst</CommandName>
+ <ButtonText>Reverse Engineer Code First</ButtonText>
+ </Strings>
+ </Button>
+
+ <Button guid="guidDbContextPackageCmdSet" id="cmdidAddCustomTemplates" priority="0x0100" type="Button">
+ <Parent guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuItemsGroup" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <Strings>
+ <CommandName>cmdidAddCustomTemplates</CommandName>
+ <ButtonText>Customize Reverse Engineer Templates</ButtonText>
+ </Strings>
+ </Button>
+
+ </Buttons>
+
+ <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
+ <Bitmaps>
+ <!-- The bitmap id is defined in a way that is a little bit different from the others:
+ the declaration starts with a guid for the bitmap strip, then there is the resource id of the
+ bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
+ inside a button definition. An important aspect of this declaration is that the element id
+ must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
+ <Bitmap guid="guidImage1" href="Resources\1.png" usedList="bmpPic1" />
+ <Bitmap guid="guidImage2" href="Resources\2.png" usedList="bmpPic2" />
+ <Bitmap guid="guidImage3" href="Resources\3.png" usedList="bmpPic3" />
+ <Bitmap guid="guidImage4" href="Resources\4.png" usedList="bmpPic4" />
+ <Bitmap guid="guidImage5" href="Resources\5.png" usedList="bmpPic5" />
+
+ </Bitmaps>
+
+ </Commands>
+
+ <CommandPlacements>
+
+ <CommandPlacement guid="guidDbContextPackageCmdSet" id="cmdidEdmMenuGroup" priority="0x100">
+ <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE" />
+ </CommandPlacement>
+
+ <CommandPlacement guid="guidDbContextPackageCmdSet" id="cmdidEdmProjectMenuGroup" priority="0x100">
+ <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_PROJNODE" />
+ </CommandPlacement>
+
+ </CommandPlacements>
+
+ <Symbols>
+ <!-- This is the package guid. -->
+ <GuidSymbol name="guidDbContextPackagePkg" value="{2b119c79-9836-46e2-b5ed-eb766cebbf7c}" />
+
+ <!-- This is the guid used to group the menu commands together -->
+ <GuidSymbol name="guidDbContextPackageCmdSet" value="{c769a05d-8d51-4919-bfe6-5f35a0eaf27e}">
+
+ <!-- Project Item Menu Entries -->
+ <IDSymbol name="cmdidViewEntityDataModel" value="0x0100" />
+ <IDSymbol name="cmdidViewEntityDataModelXml" value="0x0200" />
+ <IDSymbol name="cmdidPrecompileEntityDataModelViews" value="0x0300" />
+ <IDSymbol name="cmdidViewEntityModelDdl" value="0x0400" />
+ <IDSymbol name="cmdidEdmMenu" value="0x0500" />
+ <IDSymbol name="cmdidEdmMenuGroup" value="0x0600" />
+ <IDSymbol name="cmdidEdmMenuItemsGroup" value="0x0700" />
+ <IDSymbol name="cmdidEdmViewMenuItemsGroup" value="0x0800" />
+
+ <!-- Project Menu Entries -->
+ <IDSymbol name="cmdidReverseEngineerCodeFirst" value="0x0001" />
+ <IDSymbol name="cmdidEdmProjectMenuItemsGroup" value="0x0002" />
+ <IDSymbol name="cmdidEdmProjectMenu" value="0x0003" />
+ <IDSymbol name="cmdidEdmProjectMenuGroup" value="0x0004" />
+ <IDSymbol name="cmdidAddCustomTemplates" value="0x0005" />
+
+ </GuidSymbol>
+
+ <GuidSymbol name="guidImage1" value="{92a8e017-4f3b-4613-b78c-179f86113adb}">
+ <IDSymbol name="bmpPic1" value="1" />
+ </GuidSymbol>
+
+ <GuidSymbol name="guidImage2" value="{92a8e017-4f3b-4613-b78c-179f86177adb}">
+ <IDSymbol name="bmpPic2" value="1" />
+ </GuidSymbol>
+
+ <GuidSymbol name="guidImage3" value="{92a8e017-4f3b-4613-b78c-179f86199adb}">
+ <IDSymbol name="bmpPic3" value="1" />
+ </GuidSymbol>
+
+ <GuidSymbol name="guidImage4" value="{92a8e017-4f3b-4613-b78c-179f86009adb}">
+ <IDSymbol name="bmpPic4" value="1" />
+ </GuidSymbol>
+
+ <GuidSymbol name="guidImage5" value="{146f17c2-c8e3-4cfd-9fe2-49cc07c6d4d3}">
+ <IDSymbol name="bmpPic5" value="1" />
+ </GuidSymbol>
+ </Symbols>
+
+</CommandTable>
View
22 src/PowerTools/Extensions/CompilerErrorCollectionExtensions.cs
@@ -0,0 +1,22 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System.CodeDom.Compiler;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+
+ internal static class CompilerErrorCollectionExtensions
+ {
+ public static void HandleErrors(this CompilerErrorCollection errors, string message)
+ {
+ Contract.Requires(errors != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(message));
+
+ if (errors.HasErrors)
+ {
+ throw new CompilerErrorException(
+ message,
+ errors.Cast<CompilerError>().ToList());
+ }
+ }
+ }
+}
View
58 src/PowerTools/Extensions/CompilerErrorException.cs
@@ -0,0 +1,58 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+ using System.CodeDom.Compiler;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Runtime.Serialization;
+
+ [Serializable]
+ public class CompilerErrorException : Exception
+ {
+ private readonly IEnumerable<CompilerError> _errors;
+
+ public CompilerErrorException()
+ {
+ }
+
+ public CompilerErrorException(string message)
+ : base(message)
+ {
+ }
+
+ public CompilerErrorException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public CompilerErrorException(string message, IEnumerable<CompilerError> errors)
+ : base(message)
+ {
+ Contract.Requires(errors != null);
+
+ _errors = errors;
+ }
+
+ protected CompilerErrorException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ Contract.Requires(info != null);
+
+ _errors = (IEnumerable<CompilerError>)info.GetValue("Errors", typeof(IEnumerable<CompilerError>));
+ }
+
+ public IEnumerable<CompilerError> Errors
+ {
+ get { return _errors; }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ Contract.Requires(info != null);
+
+ info.AddValue("Errors", _errors);
+
+ base.GetObjectData(info, context);
+ }
+ }
+}
View
58 src/PowerTools/Extensions/EdmSchemaErrorException.cs
@@ -0,0 +1,58 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Data.Metadata.Edm;
+ using System.Diagnostics.Contracts;
+ using System.Runtime.Serialization;
+
+ [Serializable]
+ public class EdmSchemaErrorException : Exception
+ {
+ private readonly IEnumerable<EdmSchemaError> _errors;
+
+ public EdmSchemaErrorException()
+ {
+ }
+
+ public EdmSchemaErrorException(string message)
+ : base(message)
+ {
+ }
+
+ public EdmSchemaErrorException(string message, IEnumerable<EdmSchemaError> errors)
+ : base(message)
+ {
+ Contract.Requires(errors != null);
+
+ _errors = errors;
+ }
+
+ public EdmSchemaErrorException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ protected EdmSchemaErrorException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ Contract.Requires(info != null);
+
+ _errors = (IEnumerable<EdmSchemaError>)info.GetValue("Errors", typeof(IEnumerable<EdmSchemaError>));
+ }
+
+ public IEnumerable<EdmSchemaError> Errors
+ {
+ get { return _errors; }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ Contract.Requires(info != null);
+
+ info.AddValue("Errors", _errors);
+
+ base.GetObjectData(info, context);
+ }
+ }
+}
View
19 src/PowerTools/Extensions/IComponentModelExtensions.cs
@@ -0,0 +1,19 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+ using System.Diagnostics.Contracts;
+ using Microsoft.VisualStudio.ComponentModelHost;
+
+ internal static class IComponentModelExtensions
+ {
+ public static object GetService(this IComponentModel componentModel, Type serviceType)
+ {
+ Contract.Requires(componentModel != null);
+ Contract.Requires(serviceType != null);
+
+ return typeof(IComponentModel).GetMethod("GetService")
+ .MakeGenericMethod(serviceType)
+ .Invoke(componentModel, null);
+ }
+ }
+}
View
27 src/PowerTools/Extensions/IEnumerableOfEdmSchemaErrorExtensions.cs
@@ -0,0 +1,27 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System.Collections.Generic;
+ using System.Data.Metadata.Edm;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+
+ internal static class IEnumerableOfEdmSchemaErrorExtensions
+ {
+ public static void HandleErrors(this IEnumerable<EdmSchemaError> errors, string message)
+ {
+ Contract.Requires(errors != null);
+
+ if (errors.HasErrors())
+ {
+ throw new EdmSchemaErrorException(message, errors);
+ }
+ }
+
+ private static bool HasErrors(this IEnumerable<EdmSchemaError> errors)
+ {
+ Contract.Requires(errors != null);
+
+ return errors.Any(e => e.Severity == EdmSchemaErrorSeverity.Error);
+ }
+ }
+}
View
158 src/PowerTools/Extensions/ProjectExtensions.cs
@@ -0,0 +1,158 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Linq;
+ using System.Runtime.InteropServices;
+ using EnvDTE;
+ using Microsoft.VisualStudio.ComponentModelHost;
+ using Microsoft.VisualStudio.Shell;
+ using Microsoft.VisualStudio.Shell.Interop;
+ using IServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
+
+ internal static class ProjectExtensions
+ {
+ public const int S_OK = 0;
+ public const string WebApplicationProjectTypeGuid = "{349C5851-65DF-11DA-9384-00065B846F21}";
+ public const string WebSiteProjectTypeGuid = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}";
+
+ public static ProjectItem AddNewFile(this Project project, string path, string contents)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(path));
+
+ if (string.IsNullOrWhiteSpace(contents))
+ {
+ return null;
+ }
+
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+ project.DTE.SourceControl.CheckOutItemIfNeeded(path);
+ File.WriteAllText(path, contents);
+
+ return project.ProjectItems.AddFromFile(path);
+ }
+
+ public static string GetProjectDir(this Project project)
+ {
+ Contract.Requires(project != null);
+
+ return project.GetPropertyValue<string>("FullPath");
+ }
+
+ public static string GetTargetDir(this Project project)
+ {
+ Contract.Requires(project != null);
+
+ var fullPath = project.GetProjectDir();
+ string outputPath;
+
+ outputPath = project.GetConfigurationPropertyValue<string>("OutputPath");
+
+ return Path.Combine(fullPath, outputPath);
+ }
+
+ public static void InstallPackage(this Project project, string packageId)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(packageId));
+
+ var typeNuGetConstants = Type.GetType("NuGet.NuGetConstants, NuGet.VisualStudio", true);
+ var typeIVsPackageInstaller = Type.GetType("NuGet.VisualStudio.IVsPackageInstaller, NuGet.VisualStudio", true);
+ var typeSemanticVersion = Type.GetType("NuGet.SemanticVersion, NuGet.Core", true);
+
+ var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
+ var packageInstaller = componentModel.GetService(typeIVsPackageInstaller);
+ var source = (string)typeNuGetConstants.GetField("DefaultFeedUrl").GetValue(null);
+
+ typeIVsPackageInstaller.GetMethod(
+ "InstallPackage",
+ new[] { typeof(string), typeof(Project), typeof(string), typeSemanticVersion, typeof(bool) })
+ .Invoke(packageInstaller, new object[] { source, project, packageId, null, false });
+ }
+
+ public static bool IsWebProject(this Project project)
+ {
+ Contract.Requires(project != null);
+
+ return project.GetProjectTypes().Any(
+ g => g.EqualsIgnoreCase(WebApplicationProjectTypeGuid)
+ || g.EqualsIgnoreCase(WebSiteProjectTypeGuid));
+ }
+
+ public static bool TryBuild(this Project project)
+ {
+ Contract.Requires(project != null);
+
+ var dte = project.DTE;
+ var configuration = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
+
+ dte.Solution.SolutionBuild.BuildProject(configuration, project.UniqueName, true);
+
+ return dte.Solution.SolutionBuild.LastBuildInfo == 0;
+ }
+
+ private static T GetPropertyValue<T>(this Project project, string propertyName)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(propertyName));
+
+ var property = project.Properties.Item(propertyName);
+
+ if (property == null)
+ {
+ return default(T);
+ }
+
+ return (T)property.Value;
+ }
+
+ private static T GetConfigurationPropertyValue<T>(this Project project, string propertyName)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(propertyName));
+
+ var property = project.ConfigurationManager.ActiveConfiguration.Properties.Item(propertyName);
+
+ if (property == null)
+ {
+ return default(T);
+ }
+
+ return (T)property.Value;
+ }
+
+ private static IEnumerable<string> GetProjectTypes(this Project project)
+ {
+ Contract.Requires(project != null);
+
+ IVsSolution solution;
+ using (var serviceProvider = new ServiceProvider((IServiceProvider)project.DTE))
+ {
+ solution = (IVsSolution)serviceProvider.GetService(typeof(IVsSolution));
+ }
+
+ IVsHierarchy hierarchy;
+ var hr = solution.GetProjectOfUniqueName(project.UniqueName, out hierarchy);
+
+ if (hr != S_OK)
+ {
+ Marshal.ThrowExceptionForHR(hr);
+ }
+
+ string projectTypeGuidsString;
+
+ var aggregatableProject = (IVsAggregatableProject)hierarchy;
+ hr = aggregatableProject.GetAggregateProjectTypeGuids(out projectTypeGuidsString);
+
+ if (hr != S_OK)
+ {
+ Marshal.ThrowExceptionForHR(hr);
+ }
+
+ return projectTypeGuidsString.Split(';');
+ }
+ }
+}
View
21 src/PowerTools/Extensions/ProjectItemsExtensions.cs
@@ -0,0 +1,21 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using EnvDTE;
+
+ internal static class ProjectItemsExtensions
+ {
+ public static ProjectItem GetItem(this ProjectItems projectItems, string name)
+ {
+ Contract.Requires(projectItems != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(name));
+
+ return projectItems
+ .Cast<ProjectItem>()
+ .FirstOrDefault(
+ pi => string.Equals(pi.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+}
View
21 src/PowerTools/Extensions/SourceControlExtenstions.cs
@@ -0,0 +1,21 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System.Diagnostics.Contracts;
+ using EnvDTE;
+
+ internal static class SourceControlExtenstions
+ {
+ public static bool CheckOutItemIfNeeded(this SourceControl sourceControl, string itemName)
+ {
+ Contract.Requires(sourceControl != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(itemName));
+
+ if (sourceControl.IsItemUnderSCC(itemName) && !sourceControl.IsItemCheckedOut(itemName))
+ {
+ return sourceControl.CheckOutItem(itemName);
+ }
+
+ return false;
+ }
+ }
+}
View
12 src/PowerTools/Extensions/StringExtensions.cs
@@ -0,0 +1,12 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System;
+
+ internal static class StringExtensions
+ {
+ public static bool EqualsIgnoreCase(this string s1, string s2)
+ {
+ return string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+}
View
29 src/PowerTools/Extensions/XContainerExtensions.cs
@@ -0,0 +1,29 @@
+namespace Microsoft.DbContextPackage.Extensions
+{
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Xml.Linq;
+
+ internal static class XContainerExtensions
+ {
+ /// <summary>
+ /// Gets the first (in document order) child element with the specified local name and one of the namespaces.
+ /// </summary>
+ /// <param name="container">The node containing the child elements.</param>
+ /// <param name="namespaces">A collection of namespaces used when searching for the child element.</param>
+ /// <param name="localName">The local (unqualified) name to match.</param>
+ /// <returns>A <see cref="XElement" /> that matches the specified name and namespace, or null.</returns>
+ public static XElement Element(this XContainer container, IEnumerable<XNamespace> namespaces, string localName)
+ {
+ Contract.Requires(container != null);
+ Contract.Requires(namespaces != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(localName));
+
+ return container.Elements()
+ .FirstOrDefault(
+ e => e.Name.LocalName == localName
+ && namespaces.Contains(e.Name.Namespace));
+ }
+ }
+}
View
11 src/PowerTools/GlobalSuppressions.cs
@@ -0,0 +1,11 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project. Project-level
+// suppressions either have no target or are given a specific target
+// and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click "In Project
+// Suppression File". You do not need to add suppressions to this
+// file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
View
14 src/PowerTools/Guids.cs
@@ -0,0 +1,14 @@
+// Guids.cs
+// MUST match guids.h
+namespace Microsoft.DbContextPackage
+{
+ using System;
+
+ internal static class GuidList
+ {
+ public const string guidDbContextPackagePkgString = "2b119c79-9836-46e2-b5ed-eb766cebbf7c";
+ public const string guidDbContextPackageCmdSetString = "c769a05d-8d51-4919-bfe6-5f35a0eaf27e";
+
+ public static readonly Guid guidDbContextPackageCmdSet = new Guid(guidDbContextPackageCmdSetString);
+ }
+}
View
51 src/PowerTools/Handlers/AddCustomTemplatesHandler.cs
@@ -0,0 +1,51 @@
+namespace Microsoft.DbContextPackage.Handlers
+{
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using EnvDTE;
+ using Microsoft.DbContextPackage.Extensions;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+
+ internal class AddCustomTemplatesHandler
+ {
+ private readonly DbContextPackage _package;
+
+ public AddCustomTemplatesHandler(DbContextPackage package)
+ {
+ Contract.Requires(package != null);
+
+ _package = package;
+ }
+
+ public void AddCustomTemplates(Project project)
+ {
+ Contract.Requires(project != null);
+
+ try
+ {
+ AddTemplate(project, Templates.ContextTemplate);
+ AddTemplate(project, Templates.EntityTemplate);
+ AddTemplate(project, Templates.MappingTemplate);
+ }
+ catch (Exception ex)
+ {
+ _package.LogError(Strings.AddTemplatesError, ex);
+ }
+ }
+
+ private static void AddTemplate(Project project, string templatePath)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(templatePath));
+
+ var projectDir = project.GetProjectDir();
+
+ var filePath = Path.Combine(projectDir, templatePath);
+ var contents = Templates.GetDefaultTemplate(templatePath);
+ var item = project.AddNewFile(filePath, contents);
+ item.Properties.Item("CustomTool").Value = null;
+ }
+ }
+}
View
140 src/PowerTools/Handlers/OptimizeContextHandler.cs
@@ -0,0 +1,140 @@
+namespace Microsoft.DbContextPackage.Handlers
+{
+ using System;
+ using System.Data.Entity.Design;
+ using System.Data.Mapping;
+ using System.Data.Metadata.Edm;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Threading.Tasks;
+ using System.Windows.Forms;
+ using EnvDTE;
+ using Microsoft.DbContextPackage.Extensions;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+ using Task = System.Threading.Tasks.Task;
+
+ internal class OptimizeContextHandler
+ {
+ private readonly DbContextPackage _package;
+
+ public OptimizeContextHandler(DbContextPackage package)
+ {
+ Contract.Requires(package != null);
+
+ _package = package;
+ }
+
+ public void OptimizeContext(dynamic context)
+ {
+ Type contextType = context.GetType();
+
+ try
+ {
+ var selectedItem = _package.DTE2.SelectedItems.Item(1);
+ var selectedItemExtension = (string)selectedItem.ProjectItem.Properties.Item("Extension").Value;
+ var languageOption = selectedItemExtension == FileExtensions.CSharp
+ ? LanguageOption.GenerateCSharpCode
+ : LanguageOption.GenerateVBCode;
+ var objectContext = DbContextPackage.GetObjectContext(context);
+ var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
+
+ OptimizeContextCore(languageOption, contextType.Name, mappingCollection);
+ }
+ catch (Exception ex)
+ {
+ _package.LogError(Strings.Optimize_ContextError(contextType.Name), ex);
+ }
+ }
+
+ public void OptimizeEdmx(string inputPath)
+ {
+ Contract.Requires(!string.IsNullOrWhiteSpace(inputPath));
+
+ var baseFileName = Path.GetFileNameWithoutExtension(inputPath);
+
+ try
+ {
+ var project = _package.DTE2.SelectedItems.Item(1).ProjectItem.ContainingProject;
+ var languageOption = project.CodeModel.Language == CodeModelLanguageConstants.vsCMLanguageCSharp
+ ? LanguageOption.GenerateCSharpCode
+ : LanguageOption.GenerateVBCode;
+ var mappingCollection = new EdmxUtility(inputPath).GetMappingCollection();
+
+ OptimizeContextCore(languageOption, baseFileName, mappingCollection);
+ }
+ catch (Exception ex)
+ {
+ _package.LogError(Strings.Optimize_EdmxError(baseFileName), ex);
+ }
+ }
+
+ private void OptimizeContextCore(LanguageOption languageOption, string baseFileName, StorageMappingItemCollection mappingCollection)
+ {
+ Contract.Requires(!string.IsNullOrWhiteSpace(baseFileName));
+ Contract.Requires(mappingCollection != null);
+
+ var progressTimer = new Timer { Interval = 1000 };
+
+ try
+ {
+ var selectedItem = _package.DTE2.SelectedItems.Item(1);
+ var selectedItemPath = (string)selectedItem.ProjectItem.Properties.Item("FullPath").Value;
+ var viewGenerator = new EntityViewGenerator(languageOption);
+ var viewsFileName = baseFileName
+ + ".Views"
+ + ((languageOption == LanguageOption.GenerateCSharpCode)
+ ? FileExtensions.CSharp
+ : FileExtensions.VisualBasic);
+ var viewsPath = Path.Combine(
+ Path.GetDirectoryName(selectedItemPath),
+ viewsFileName);
+
+ _package.DTE2.SourceControl.CheckOutItemIfNeeded(viewsPath);
+
+ var progress = 1;
+ progressTimer.Tick += (sender, e) =>
+ {
+ _package.DTE2.StatusBar.Progress(true, string.Empty, progress, 100);
+ progress = progress == 100 ? 1 : progress + 1;
+ _package.DTE2.StatusBar.Text = Strings.Optimize_Begin(baseFileName);
+ };
+
+ progressTimer.Start();
+
+ Task.Factory.StartNew(
+ () =>
+ {
+ var errors = viewGenerator.GenerateViews(mappingCollection, viewsPath);
+ errors.HandleErrors(Strings.Optimize_SchemaError(baseFileName));
+ })
+ .ContinueWith(
+ t =>
+ {
+ progressTimer.Stop();
+ _package.DTE2.StatusBar.Progress(false);
+
+ if (t.IsFaulted)
+ {
+ _package.LogError(Strings.Optimize_Error(baseFileName), t.Exception);
+
+ return;
+ }
+
+ selectedItem.ProjectItem.ContainingProject.ProjectItems.AddFromFile(viewsPath);
+ _package.DTE2.ItemOperations.OpenFile(viewsPath);
+
+ _package.DTE2.StatusBar.Text = Strings.Optimize_End(baseFileName, Path.GetFileName(viewsPath));
+ },
+ TaskScheduler.FromCurrentSynchronizationContext());
+ }
+ catch
+ {
+ progressTimer.Stop();
+ _package.DTE2.StatusBar.Progress(false);
+
+ throw;
+ }
+ }
+ }
+}
View
364 src/PowerTools/Handlers/ReverseEngineerCodeFirstHandler.cs
@@ -0,0 +1,364 @@
+namespace Microsoft.DbContextPackage.Handlers
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Data.Common;
+ using System.Data.Entity.Design;
+ using System.Data.Entity.Design.PluralizationServices;
+ using System.Data.Metadata.Edm;
+ using System.Data.SqlClient;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using System.Xml;
+ using Microsoft.DbContextPackage.Extensions;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+ using Microsoft.VisualStudio.Data.Core;
+ using Microsoft.VisualStudio.Data.Services;
+ using Microsoft.VisualStudio.Shell;
+ using Project = EnvDTE.Project;
+
+ internal class ReverseEngineerCodeFirstHandler
+ {
+ private static readonly IEnumerable<EntityStoreSchemaFilterEntry> _storeMetadataFilters = new[]
+ {
+ new EntityStoreSchemaFilterEntry(null, null, "EdmMetadata", EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Exclude),
+ new EntityStoreSchemaFilterEntry(null, null, "__MigrationHistory", EntityStoreSchemaFilterObjectTypes.Table, EntityStoreSchemaFilterEffect.Exclude)
+ };
+ private readonly DbContextPackage _package;
+
+ public ReverseEngineerCodeFirstHandler(DbContextPackage package)
+ {
+ Contract.Requires(package != null);
+
+ _package = package;
+ }
+
+ public void ReverseEngineerCodeFirst(Project project)
+ {
+ Contract.Requires(project != null);
+
+ try
+ {
+ // Show dialog with SqlClient selected by default
+ var dialogFactory = _package.GetService<IVsDataConnectionDialogFactory>();
+ var dialog = dialogFactory.CreateConnectionDialog();
+ dialog.AddAllSources();
+ dialog.SelectedSource = new Guid("067ea0d9-ba62-43f7-9106-34930c60c528");
+ var dialogResult = dialog.ShowDialog(connect: true);
+
+ if (dialogResult != null)
+ {
+ // Find connection string and provider
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_LoadSchema;
+ var connection = (DbConnection)dialogResult.GetLockedProviderObject();
+ var connectionString = connection.ConnectionString;
+ var providerManager = (IVsDataProviderManager)Package.GetGlobalService(typeof(IVsDataProviderManager));
+ IVsDataProvider dp;
+ providerManager.Providers.TryGetValue(dialogResult.Provider, out dp);
+ var providerInvariant = (string)dp.GetProperty("InvariantName");
+
+ // Load store schema
+ var storeGenerator = new EntityStoreSchemaGenerator(providerInvariant, connectionString, "dbo");
+ storeGenerator.GenerateForeignKeyProperties = true;
+ var errors = storeGenerator.GenerateStoreMetadata(_storeMetadataFilters).Where(e => e.Severity == EdmSchemaErrorSeverity.Error);
+ errors.HandleErrors(Strings.ReverseEngineer_SchemaError);
+
+ // Generate default mapping
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateMapping;
+ var contextName = connection.Database.Replace(" ", string.Empty).Replace(".", string.Empty) + "Context";
+ var modelGenerator = new EntityModelSchemaGenerator(storeGenerator.EntityContainer, "DefaultNamespace", contextName);
+ modelGenerator.PluralizationService = PluralizationService.CreateService(new CultureInfo("en"));
+ modelGenerator.GenerateForeignKeyProperties = true;
+ modelGenerator.GenerateMetadata();
+
+ // Pull out info about types to be generated
+ var entityTypes = modelGenerator.EdmItemCollection.OfType<EntityType>().ToArray();
+ var mappings = new EdmMapping(modelGenerator, storeGenerator.StoreItemCollection);
+
+ // Find the project to add the code to
+ var vsProject = (VSLangProj.VSProject)project.Object;
+ var projectDirectory = new FileInfo(project.FileName).Directory;
+ var projectNamespace = (string)project.Properties.Item("RootNamespace").Value;
+ var references = vsProject.References.Cast<VSLangProj.Reference>();
+
+ if (!references.Any(r => r.Name == "EntityFramework"))
+ {
+ // Add EF References
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_InstallEntityFramework;
+
+ try
+ {
+ project.InstallPackage("EntityFramework");
+ }
+ catch (Exception ex)
+ {
+ _package.LogError(Strings.ReverseEngineer_InstallEntityFrameworkError, ex);
+ }
+ }
+
+ // Generate Entity Classes and Mappings
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateClasses;
+ var templateProcessor = new TemplateProcessor(project);
+ var modelsNamespace = projectNamespace + ".Models";
+ var modelsDirectory = Path.Combine(projectDirectory.FullName, "Models");
+ var mappingNamespace = modelsNamespace + ".Mapping";
+ var mappingDirectory = Path.Combine(modelsDirectory, "Mapping");
+ var entityFrameworkVersion = GetEntityFrameworkVersion(references);
+
+ foreach (var entityType in entityTypes)
+ {
+ // Generate the code file
+ var entityHost = new EfTextTemplateHost
+ {
+ EntityType = entityType,
+ EntityContainer = modelGenerator.EntityContainer,
+ Namespace = modelsNamespace,
+ ModelsNamespace = modelsNamespace,
+ MappingNamespace = mappingNamespace,
+ EntityFrameworkVersion = entityFrameworkVersion,
+ TableSet = mappings.EntityMappings[entityType].Item1,
+ PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2,
+ ManyToManyMappings = mappings.ManyToManyMappings
+ };
+ var entityContents = templateProcessor.Process(Templates.EntityTemplate, entityHost);
+
+ var filePath = Path.Combine(modelsDirectory, entityType.Name + entityHost.FileExtension);
+ project.AddNewFile(filePath, entityContents);
+
+ var mappingHost = new EfTextTemplateHost
+ {
+ EntityType = entityType,
+ EntityContainer = modelGenerator.EntityContainer,
+ Namespace = mappingNamespace,
+ ModelsNamespace = modelsNamespace,
+ MappingNamespace = mappingNamespace,
+ EntityFrameworkVersion = entityFrameworkVersion,
+ TableSet = mappings.EntityMappings[entityType].Item1,
+ PropertyToColumnMappings = mappings.EntityMappings[entityType].Item2,
+ ManyToManyMappings = mappings.ManyToManyMappings
+ };
+ var mappingContents = templateProcessor.Process(Templates.MappingTemplate, mappingHost);
+
+ var mappingFilePath = Path.Combine(mappingDirectory, entityType.Name + "Map" + mappingHost.FileExtension);
+ project.AddNewFile(mappingFilePath, mappingContents);
+ }
+
+ // Generate Context
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_GenerateContext;
+ var contextHost = new EfTextTemplateHost
+ {
+ EntityContainer = modelGenerator.EntityContainer,
+ Namespace = modelsNamespace,
+ ModelsNamespace = modelsNamespace,
+ MappingNamespace = mappingNamespace,
+ EntityFrameworkVersion = entityFrameworkVersion
+ };
+ var contextContents = templateProcessor.Process(Templates.ContextTemplate, contextHost);
+
+ var contextFilePath = Path.Combine(modelsDirectory, modelGenerator.EntityContainer.Name + contextHost.FileExtension);
+ var contextItem = project.AddNewFile(contextFilePath, contextContents);
+ AddConnectionStringToConfigFile(project, connectionString, providerInvariant, modelGenerator.EntityContainer.Name);
+
+ if (contextItem != null)
+ {
+ // Open context class when done
+ _package.DTE2.ItemOperations.OpenFile(contextFilePath);
+ }
+
+ _package.DTE2.StatusBar.Text = Strings.ReverseEngineer_Complete;
+ }
+ }
+ catch (Exception exception)
+ {
+ _package.LogError(Strings.ReverseEngineer_Error, exception);
+ }
+ }
+
+ private static Version GetEntityFrameworkVersion(IEnumerable<VSLangProj.Reference> references)
+ {
+ var entityFrameworkReference = references.FirstOrDefault(r => r.Name == "EntityFramework");
+
+ if (entityFrameworkReference != null)
+ {
+ return new Version(entityFrameworkReference.Version);
+ }
+
+ return null;
+ }
+
+ private static void AddConnectionStringToConfigFile(Project project, string connectionString, string providerInvariant, string connectionStringName)
+ {
+ Contract.Requires(project != null);
+ Contract.Requires(!string.IsNullOrWhiteSpace(providerInvariant));
+ Contract.Requires(!string.IsNullOrWhiteSpace(connectionStringName));
+
+ // Find App.config or Web.config
+ var configFilePath = Path.Combine(
+ project.GetProjectDir(),
+ project.IsWebProject()
+ ? "Web.config"
+ : "App.config");
+
+ // Either load up the existing file or create a blank file
+ var config = ConfigurationManager.OpenMappedExeConfiguration(
+ new ExeConfigurationFileMap { ExeConfigFilename = configFilePath },
+ ConfigurationUserLevel.None);
+
+ // Find or create the connectionStrings section
+ var connectionStringSettings = config.ConnectionStrings
+ .ConnectionStrings
+ .Cast<ConnectionStringSettings>()
+ .FirstOrDefault(css => css.Name == connectionStringName);
+
+ if (connectionStringSettings == null)
+ {
+ connectionStringSettings = new ConnectionStringSettings
+ {
+ Name = connectionStringName
+ };
+
+ config.ConnectionStrings
+ .ConnectionStrings
+ .Add(connectionStringSettings);
+ }
+
+ // Add in the new connection string
+ connectionStringSettings.ProviderName = providerInvariant;
+ connectionStringSettings.ConnectionString = FixUpConnectionString(connectionString, providerInvariant);
+
+ project.DTE.SourceControl.CheckOutItemIfNeeded(configFilePath);
+ config.Save();
+
+ // Add any new file to the project
+ project.ProjectItems.AddFromFile(configFilePath);
+ }
+
+ private static string FixUpConnectionString(string connectionString, string providerName)
+ {
+ Contract.Requires(!string.IsNullOrWhiteSpace(providerName));
+
+ if (providerName != "System.Data.SqlClient")
+ {
+ return connectionString;
+ }
+
+ var builder = new SqlConnectionStringBuilder(connectionString)
+ {
+ MultipleActiveResultSets = true
+ };
+ builder.Remove("Pooling");
+
+ return builder.ToString();
+ }
+
+ private class EdmMapping
+ {
+ public EdmMapping(EntityModelSchemaGenerator mcGenerator, StoreItemCollection store)
+ {
+ Contract.Requires(mcGenerator != null);
+ Contract.Requires(store != null);
+
+ // Pull mapping xml out
+ var mappingDoc = new XmlDocument();
+ var mappingXml = new StringBuilder();
+
+ using (var textWriter = new StringWriter(mappingXml))
+ {
+ mcGenerator.WriteStorageMapping(new XmlTextWriter(textWriter));
+ }
+
+ mappingDoc.LoadXml(mappingXml.ToString());
+
+ var entitySets = mcGenerator.EntityContainer.BaseEntitySets.OfType<EntitySet>();
+ var associationSets = mcGenerator.EntityContainer.BaseEntitySets.OfType<AssociationSet>();
+ var tableSets = store.GetItems<EntityContainer>().Single().BaseEntitySets.OfType<EntitySet>();
+
+ this.EntityMappings = BuildEntityMappings(mappingDoc, entitySets, tableSets);
+ this.ManyToManyMappings = BuildManyToManyMappings(mappingDoc, associationSets, tableSets);
+ }
+
+ public Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> EntityMappings { get; set; }
+
+ public Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> ManyToManyMappings { get; set; }
+
+ private static Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> BuildManyToManyMappings(XmlDocument mappingDoc, IEnumerable<AssociationSet> associationSets, IEnumerable<EntitySet> tableSets)
+ {
+ Contract.Requires(mappingDoc != null);
+ Contract.Requires(associationSets != null);
+ Contract.Requires(tableSets != null);
+
+ // Build mapping for each association
+ var mappings = new Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>>();
+ var namespaceManager = new XmlNamespaceManager(mappingDoc.NameTable);
+ namespaceManager.AddNamespace("ef", mappingDoc.ChildNodes[0].NamespaceURI);
+ foreach (var associationSet in associationSets.Where(a => !a.ElementType.AssociationEndMembers.Where(e => e.RelationshipMultiplicity != RelationshipMultiplicity.Many).Any()))
+ {
+ var setMapping = mappingDoc.SelectSingleNode(string.Format("//ef:AssociationSetMapping[@Name=\"{0}\"]", associationSet.Name), namespaceManager);
+ var tableName = setMapping.Attributes["StoreEntitySet"].Value;
+ var tableSet = tableSets.Single(s => s.Name == tableName);
+
+ var endMappings = new Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>();
+ foreach (var end in associationSet.AssociationSetEnds)
+ {
+ var propertyToColumnMappings = new Dictionary<EdmMember, string>();
+ var endMapping = setMapping.SelectSingleNode(string.Format("./ef:EndProperty[@Name=\"{0}\"]", end.Name), namespaceManager);
+ foreach (XmlNode fk in endMapping.ChildNodes)
+ {
+ var propertyName = fk.Attributes["Name"].Value;
+ var property = end.EntitySet.ElementType.Properties[propertyName];
+ var columnName = fk.Attributes["ColumnName"].Value;
+ propertyToColumnMappings.Add(property, columnName);
+ }
+
+ endMappings.Add(end.CorrespondingAssociationEndMember, propertyToColumnMappings);
+ }
+
+ mappings.Add(associationSet.ElementType, Tuple.Create(tableSet, endMappings));
+ }
+
+ return mappings;
+ }
+
+ private static Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> BuildEntityMappings(XmlDocument mappingDoc, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
+ {
+ Contract.Requires(mappingDoc != null);
+ Contract.Requires(entitySets != null);
+ Contract.Requires(tableSets != null);
+
+ // Build mapping for each type
+ var mappings = new Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>>();
+ var namespaceManager = new XmlNamespaceManager(mappingDoc.NameTable);
+ namespaceManager.AddNamespace("ef", mappingDoc.ChildNodes[0].NamespaceURI);
+ foreach (var entitySet in entitySets)
+ {
+ // Post VS2010 builds use a different structure for mapping
+ var setMapping = mappingDoc.ChildNodes[0].NamespaceURI == "http://schemas.microsoft.com/ado/2009/11/mapping/cs"
+ ? mappingDoc.SelectSingleNode(string.Format("//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", entitySet.Name), namespaceManager)
+ : mappingDoc.SelectSingleNode(string.Format("//ef:EntitySetMapping[@Name=\"{0}\"]", entitySet.Name), namespaceManager);
+
+ var tableName = setMapping.Attributes["StoreEntitySet"].Value;
+ var tableSet = tableSets.Single(s => s.Name == tableName);
+
+ var propertyMappings = new Dictionary<EdmProperty, EdmProperty>();
+ foreach (var prop in entitySet.ElementType.Properties)
+ {
+ var propMapping = setMapping.SelectSingleNode(string.Format("./ef:ScalarProperty[@Name=\"{0}\"]", prop.Name), namespaceManager);
+ var columnName = propMapping.Attributes["ColumnName"].Value;
+ var columnProp = tableSet.ElementType.Properties[columnName];
+
+ propertyMappings.Add(prop, columnProp);
+ }
+
+ mappings.Add(entitySet.ElementType, Tuple.Create(tableSet, propertyMappings));
+ }
+
+ return mappings;
+ }
+ }
+ }
+}
View
72 src/PowerTools/Handlers/ViewContextHandler.cs
@@ -0,0 +1,72 @@
+namespace Microsoft.DbContextPackage.Handlers
+{
+ using System;
+ using System.ComponentModel.Design;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Reflection;
+ using System.Xml;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+
+ internal class ViewContextHandler
+ {
+ private readonly DbContextPackage _package;
+
+ public ViewContextHandler(DbContextPackage package)
+ {
+ Contract.Requires(package != null);
+
+ _package = package;
+ }
+
+ public void ViewContext(MenuCommand menuCommand, dynamic context, Type systemContextType)
+ {
+ Contract.Requires(menuCommand != null);
+ Contract.Requires(systemContextType != null);
+
+ Type contextType = context.GetType();
+
+ try
+ {
+ var filePath = Path.Combine(
+ Path.GetTempPath(),
+ contextType.Name
+ + (menuCommand.CommandID.ID == PkgCmdIDList.cmdidViewEntityDataModel
+ ? FileExtensions.EntityDataModel
+ : FileExtensions.Xml));
+
+ if (File.Exists(filePath))
+ {
+ File.SetAttributes(filePath, FileAttributes.Normal);
+ }
+
+ using (var fileStream = File.Create(filePath))
+ {
+ using (var xmlWriter = XmlWriter.Create(fileStream, new XmlWriterSettings { Indent = true }))
+ {
+ var edmxWriterType = systemContextType.Assembly.GetType("System.Data.Entity.Infrastructure.EdmxWriter");
+
+ if (edmxWriterType != null)
+ {
+ edmxWriterType.InvokeMember(
+ "WriteEdmx",
+ BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
+ null,
+ null,
+ new object[] { context, xmlWriter });
+ }
+ }
+ }
+
+ _package.DTE2.ItemOperations.OpenFile(filePath);
+
+ File.SetAttributes(filePath, FileAttributes.ReadOnly);
+ }
+ catch (Exception exception)
+ {
+ _package.LogError(Strings.ViewContextError(contextType.Name), exception);
+ }
+ }
+ }
+}
View
48 src/PowerTools/Handlers/ViewDdlHandler.cs
@@ -0,0 +1,48 @@
+namespace Microsoft.DbContextPackage.Handlers
+{
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using Microsoft.DbContextPackage.Resources;
+ using Microsoft.DbContextPackage.Utilities;
+
+ internal class ViewDdlHandler
+ {
+ private readonly DbContextPackage _package;
+
+ public ViewDdlHandler(DbContextPackage package)
+ {
+ Contract.Requires(package != null);
+
+ _package = package;
+ }
+
+ public void ViewDdl(dynamic context)
+ {
+ Type contextType = context.GetType();
+
+ try
+ {
+ var filePath = Path.Combine(
+ Path.GetTempPath(),
+ contextType.Name + FileExtensions.Sql);
+
+ if (File.Exists(filePath))
+ {
+ File.SetAttributes(filePath, FileAttributes.Normal);
+ }
+
+ var objectContext = DbContextPackage.GetObjectContext(context);
+
+ File.WriteAllText(filePath, objectContext.CreateDatabaseScript());
+ File.SetAttributes(filePath, FileAttributes.ReadOnly);
+
+ _package.DTE2.ItemOperations.OpenFile(filePath);
+ }
+ catch (Exception exception)
+ {
+ _package.LogError(Strings.ViewDdlError(contextType.Name), exception);
+ }
+ }
+ }
+}
View
BIN  src/PowerTools/License.rtf
Binary file not shown
View
14 src/PowerTools/PkgCmdID.cs
@@ -0,0 +1,14 @@
+// PkgCmdID.cs
+// MUST match PkgCmdID.h
+namespace Microsoft.DbContextPackage
+{
+ internal static class PkgCmdIDList
+ {
+ public const uint cmdidViewEntityDataModel = 0x100;
+ public const uint cmdidViewEntityDataModelXml = 0x200;
+ public const uint cmdidPrecompileEntityDataModelViews = 0x300;
+ public const uint cmdidViewEntityModelDdl = 0x400;
+ public const uint cmdidReverseEngineerCodeFirst = 0x001;
+ public const uint cmdidCustomizeReverseEngineerTemplates = 0x005;
+ }
+}
View
261 src/PowerTools/PowerTools.csproj
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ProjectGuid>{16CAD3A8-FCE0-4BC1-901A-16957CF24BD6}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Microsoft.DbContextPackage</RootNamespace>
+ <AssemblyName>EFPowerTools</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <StartAction>Program</StartAction>
+ <StartProgram>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0@InstallDir)devenv.exe</StartProgram>
+ <StartArguments>/rootsuffix Exp</StartArguments>
+ <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
+ <CodeAnalysisRuleSet>..\Strict.ruleset</CodeAnalysisRuleSet>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;CODE_ANALYSIS;CONTRACTS_FULL</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsInferRequires>False</CodeContractsInferRequires>
+ <CodeContractsInferEnsures>False</CodeContractsInferEnsures>
+ <CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
+ <CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
+ <CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
+ <CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
+ <CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
+ <CodeContractsDisjunctiveRequires>False</CodeContractsDisjunctiveRequires>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly>EFPowerTools</CodeContractsCustomRewriterAssembly>
+ <CodeContractsCustomRewriterClass>Microsoft.DbContextPackage.Utilities.RuntimeFailureMethods</CodeContractsCustomRewriterClass>
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>DoNotBuild</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;CODE_ANALYSIS;CONTRACTS_FULL</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>True</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsInferRequires>False</CodeContractsInferRequires>
+ <CodeContractsInferEnsures>False</CodeContractsInferEnsures>
+ <CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
+ <CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
+ <CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
+ <CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
+ <CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
+ <CodeContractsDisjunctiveRequires>False</CodeContractsDisjunctiveRequires>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly>EFPowerTools</CodeContractsCustomRewriterAssembly>
+ <CodeContractsCustomRewriterClass>Microsoft.DbContextPackage.Utilities.RuntimeFailureMethods</CodeContractsCustomRewriterClass>
+ <CodeContractsLibPaths />
+ <CodeContractsExtraRewriteOptions />
+ <CodeContractsExtraAnalysisOptions />
+ <CodeContractsBaseLineFile />
+ <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>DoNotBuild</CodeContractsReferenceAssembly>
+ <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.Entity" />
+ <Reference Include="System.Data.Entity.Design" />
+ <Reference Include="System.Design" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="Microsoft.VisualStudio.ComponentModelHost, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Data.Core, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Data.Services, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Shell.10.0">
+ <Private>false</Private>
+ </Reference>
+ <Reference Include="Microsoft.VisualStudio.Shell.Design, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
+ <Reference Include="Microsoft.VisualStudio.TextTemplating.Interfaces.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="VSLangProj, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <COMReference Include="EnvDTE">
+ <Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE80">
+ <Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Extensions\CompilerErrorCollectionExtensions.cs" />
+ <Compile Include="Extensions\CompilerErrorException.cs" />
+ <Compile Include="Extensions\EdmSchemaErrorException.cs" />
+ <Compile Include="Extensions\IComponentModelExtensions.cs" />
+ <Compile Include="Extensions\IEnumerableOfEdmSchemaErrorExtensions.cs" />
+ <Compile Include="Extensions\ProjectExtensions.cs" />
+ <Compile Include="Extensions\ProjectItemsExtensions.cs" />
+ <Compile Include="Extensions\SourceControlExtenstions.cs" />
+ <Compile Include="Extensions\StringExtensions.cs" />
+ <Compile Include="Extensions\XContainerExtensions.cs" />
+ <Compile Include="Handlers\AddCustomTemplatesHandler.cs" />
+ <Compile Include="Handlers\OptimizeContextHandler.cs" />
+ <Compile Include="Handlers\ReverseEngineerCodeFirstHandler.cs" />
+ <Compile Include="Handlers\ViewContextHandler.cs" />
+ <Compile Include="Handlers\ViewDdlHandler.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Properties\InternalsVisibleTo.cs" />
+ <Compile Include="Properties\Resources.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.tt</DependentUpon>
+ </Compile>
+ <Compile Include="Utilities\EdmxUtility.cs" />
+ <Compile Include="Utilities\EfTextTemplateHost.cs" />
+ <Compile Include="Utilities\FileExtensions.cs" />
+ <Compile Include="Utilities\RuntimeFailureMethods.cs" />
+ <Compile Include="Utilities\TemplateProcessor.cs" />
+ <Compile Include="Utilities\Templates.cs" />
+ <Compile Include="DbContextPackage.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Guids.cs" />
+ <Compile Include="PkgCmdID.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Resources\Package.ico" />
+ <Content Include="db.png">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <Content Include="License.rtf">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <Content Include="menu.png">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="CodeTemplates\ReverseEngineerCodeFirst\Context.tt" />
+ <EmbeddedResource Include="CodeTemplates\ReverseEngineerCodeFirst\Entity.tt" />
+ <EmbeddedResource Include="CodeTemplates\ReverseEngineerCodeFirst\Mapping.tt" />
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <SubType>Designer</SubType>
+ </EmbeddedResource>