1 <#@ include file="EF.Reverse.POCO.Core.ttinclude" #> 2 <# 3 // v2.18.1 4 // Please make changes to the settings below. 5 // All you have to do is save this file, and the output file(s) is/are generated. Compiling does not regenerate the file(s). 6 7 // Main settings ********************************************************************************************************************** 8 // Namespace = ""; // Override the default namespace here 9 DbContextName = "MyDbContext"; 10 DbContextInterfaceBaseClasses = "System.IDisposable"; // Specify what the base classes are for your database context interface 11 DbContextBaseClass = "System.Data.Entity.DbContext"; // Specify what the base class is for your DbContext. For ASP.NET Identity use "IdentityDbContext<ApplicationUser>" 12 ConnectionStringName = "MyDbContext"; // Searches for this connection string in config files listed below 13 TargetFrameworkVersion = "4.51"; // Please set this to your .NET framework version, 4.0, 4.5, 4.51, etc. 14 ConfigurationClassName = "Configuration"; // Configuration, Mapping, Map, etc. This is appended to the Poco class name to configure the mappings. 15 ConfigFilenameSearchOrder = new[] { "app.config", "web.config", "app.config.transform", "web.config.transform" }; // Add more here if required. The config files are searched for in the local project first, then the whole solution second. 16 MakeClassesPartial = false; 17 GenerateSeparateFiles = false; 18 UseCamelCase = true; // This will rename the tables & fields to use CamelCase. If false table & field names will be left alone. 19 IncludeComments = true; // Adds comments to the generated code 20 IncludeExtendedPropertyComments = ExtendedPropertyCommentsStyle.InSummaryBlock; // Adds extended properties as comments to the generated code 21 IncludeViews = true; 22 IncludeStoredProcedures = true; 23 IncludeTableValuedFunctions = false; // If true, you must also install the "EntityFramework.CodeFirstStoreFunctions" Nuget Package. 24 DisableGeographyTypes = false; // Turns off use of System.Data.Entity.Spatial.DbGeography and System.Data.Entity.Spatial.DbGeometry as OData doesn‘t support entities with geometry/geography types. 25 CollectionType = "System.Collections.Generic.List"; // Determines the type of collection for the Navigation Properties. "ObservableCollection" for example. Add "System.Collections.ObjectModel" to AdditionalNamespaces if setting the CollectionType = "ObservableCollection". 26 AddUnitTestingDbContext = true; // Will add a FakeDbContext and FakeDbSet for easy unit testing 27 IncludeQueryTraceOn9481Flag = false; // If SqlServer 2014 appears frozen / take a long time when this file is saved, try setting this to true (you will also need elevated privileges). 28 AdditionalNamespaces = new[] { "" }; // To include extra namespaces, include them here. i.e. "Microsoft.AspNet.Identity.EntityFramework" 29 AdditionalContextInterfaceItems = new[] // To include extra db context interface items, include them here. Also set MakeClassesPartial=true, and implement the partial DbContext class functions. 30 { 31 "" // example: "void SetAutoDetectChangesEnabled(bool flag);" 32 }; 33 // If you need to serialize your entities with the JsonSerializer from Newtonsoft, this would serialize 34 // all properties including the Reverse Navigation and Foreign Keys. The simplest way to exclude them is 35 // to use the data annotation [JsonIgnore] on reverse navigation and foreign keys. 36 AdditionalReverseNavigationsDataAnnotations = new string[] // Data Annotations for ReverseNavigationProperty. 37 { 38 // "JsonIgnore" 39 }; 40 AdditionalForeignKeysDataAnnotations = new string[] // Data Annotations for ForeignKeys. 41 { 42 // "JsonIgnore" 43 }; 44 45 // Migrations ************************************************************************************************************************* 46 MigrationConfigurationFileName = ""; // null or empty to not create migrations 47 MigrationStrategy = "MigrateDatabaseToLatestVersion"; // MigrateDatabaseToLatestVersion, CreateDatabaseIfNotExists or DropCreateDatabaseIfModelChanges 48 ContextKey = ""; // Sets the string used to distinguish migrations belonging to this configuration from migrations belonging to other configurations using the same database. This property enables migrations from multiple different models to be applied to applied to a single database. 49 AutomaticMigrationsEnabled = true; 50 AutomaticMigrationDataLossAllowed = true; // if true, can drop fields and lose data during automatic migration 51 52 // Pluralization ********************************************************************************************************************** 53 // To turn off pluralization, use: 54 // Inflector.PluralizationService = null; 55 // Default pluralization, use: 56 // Inflector.PluralizationService = new EnglishPluralizationService(); 57 // For Spanish pluralization: 58 // 1. Intall the "EF6.Contrib" Nuget Package. 59 // 2. Add the following to the top of this file and adjust path, and remove the space between the angle bracket and # at the beginning and end. 60 // < #@ assembly name="your full path to \EntityFramework.Contrib.dll" # > 61 // 3. Change the line below to: Inflector.PluralizationService = new SpanishPluralizationService(); 62 Inflector.PluralizationService = new EnglishPluralizationService(new[] 63 { 64 // Create custom ("Singular", "Plural") forms for one-off words as needed 65 new CustomPluralizationEntry("LiveQuiz", "LiveQuizzes"), 66 new CustomPluralizationEntry("Course", "Courses"), 67 new CustomPluralizationEntry("CustomerStatus", "CustomerStatus"), // Use same value to prevent pluralisation 68 new CustomPluralizationEntry("EmployeeStatus", "EmployeeStatus") 69 }); 70 71 72 // Elements to generate *************************************************************************************************************** 73 // Add the elements that should be generated when the template is executed. 74 // Multiple projects can now be used that separate the different concerns. 75 ElementsToGenerate = Elements.Poco | Elements.Context | Elements.UnitOfWork | Elements.PocoConfiguration; 76 77 // Use these namespaces to specify where the different elements now live. These may even be in different assemblies. 78 // Please note this does not create the files in these locations, it only adds a using statement to say where they are. 79 // I show how this works on the video from 26:08 onwards. 80 // The way to do this is to add the "EntityFramework Reverse POCO Code First Generator" into each of these folders. 81 // Then set the .tt to only generate the relevant section you need by setting 82 // ElementsToGenerate = Elements.Poco; in your Entity folder, 83 // ElementsToGenerate = Elements.Context | Elements.UnitOfWork; in your Context folder, 84 // ElementsToGenerate = Elements.PocoConfiguration; in your Maps folder. 85 // PocoNamespace = "YourProject.Entities"; 86 // ContextNamespace = "YourProject.Context"; 87 // UnitOfWorkNamespace = "YourProject.Context"; 88 // PocoConfigurationNamespace = "YourProject.Maps"; 89 // You also need to set the following to the namespace where they now live: 90 PocoNamespace = ""; 91 ContextNamespace = ""; 92 UnitOfWorkNamespace = ""; 93 PocoConfigurationNamespace = ""; 94 95 96 // Schema ***************************************************************************************************************************** 97 // If there are multiple schemas, then the table name is prefixed with the schema, except for dbo. 98 // Ie. dbo.hello will be Hello. 99 // abc.hello will be AbcHello. 100 PrependSchemaName = true; // Control if the schema name is prepended to the table name 101 102 103 // Filtering ************************************************************************************************************************** 104 // Use the following table/view name regex filters to include or exclude tables/views 105 // Exclude filters are checked first and tables matching filters are removed. 106 // * If left null, none are excluded. 107 // * If not null, any tables matching the regex are excluded. 108 // Include filters are checked second. 109 // * If left null, all are included. 110 // * If not null, only the tables matching the regex are included. 111 // Example: TableFilterExclude = new Regex(".*auto.*"); 112 // TableFilterInclude = new Regex("(.*_FR_.*)|(data_.*)"); 113 // TableFilterInclude = new Regex("^table_name1$|^table_name2$|etc"); 114 // ColumnFilterExclude = new Regex("^FK_.*$"); 115 SchemaFilterExclude = null; 116 SchemaFilterInclude = null; 117 TableFilterExclude = null; 118 TableFilterInclude = null; 119 ColumnFilterExclude = null; 120 121 // Stored Procedures ****************************************************************************************************************** 122 // Use the following regex filters to include or exclude stored procedures 123 StoredProcedureFilterExclude = null; 124 StoredProcedureFilterInclude = null; 125 126 127 // Table renaming ********************************************************************************************************************* 128 // Use the following function to rename tables such as tblOrders to Orders, Shipments_AB to Shipments, etc. 129 // Example: 130 /*TableRename = (name, schema) => 131 { 132 if (name.StartsWith("tbl")) 133 name = name.Remove(0, 3); 134 return name.Replace("_AB", ""); 135 };*/ 136 TableRename = (name, schema) => name; // Do nothing by default 137 138 // Column modification***************************************************************************************************************** 139 // Use the following list to replace column byte types with Enums. 140 // As long as the type can be mapped to your new type, all is well. 141 //EnumsDefinitions.Add(new EnumDefinition { Schema = "dbo", Table = "match_table_name", Column = "match_column_name", EnumType = "name_of_enum" }); 142 //EnumsDefinitions.Add(new EnumDefinition { Schema = "dbo", Table = "OrderHeader", Column = "OrderStatus", EnumType = "OrderStatusType" }); // This will replace OrderHeader.OrderStatus type to be an OrderStatusType enum 143 144 // Use the following function if you need to apply additional modifications to a column 145 // eg. normalise names etc. 146 UpdateColumn = (Column column, Table table) => 147 { 148 // Example 149 //if (column.NameHumanCase == "PkId") 150 // column.NameHumanCase = "Id"; 151 152 // Perform Enum property type replacement 153 var enumDefinition = EnumsDefinitions.FirstOrDefault(e => 154 (e.Schema.ToLowerInvariant() == table.Schema.ToLowerInvariant()) && 155 (e.Table == table.Name || e.Table == table.NameHumanCase) && 156 (e.Column == column.Name || e.Column == column.NameHumanCase)); 157 158 if (enumDefinition != null) 159 column.PropertyType = enumDefinition.EnumType; 160 161 return column; 162 }; 163 164 // StoredProcedure renaming ************************************************************************************************************ 165 // Use the following function to rename stored procs such as sp_CreateOrderHistory to CreateOrderHistory, my_sp_shipments to Shipments, etc. 166 // Example: 167 /*StoredProcedureRename = (name, schema) => 168 { 169 if (name.StartsWith("sp_")) 170 name = name.Remove(0, 3); 171 return name.Replace("my_sp_", ""); 172 };*/ 173 StoredProcedureRename = (name, schema) => name; // Do nothing by default 174 175 // StoredProcedure return types ******************************************************************************************************* 176 // Override generation of return models for stored procedures that return entities. 177 // If a stored procedure returns an entity, add it to the list below. 178 // This will suppress the generation of the return model, and instead return the entity. 179 // Example: Proc name Return this entity type instead 180 //StoredProcedureReturnTypes.Add("SalesByYear", "SummaryOfSalesByYear"); 181 182 183 // WCF ******************************************************************************************************************************** 184 // This is only intended as a helper, to get you started creating WCF contracts, and to save a lot of typing. 185 AddWcfDataAttributes = false; 186 ExtraWcfDataContractAttributes = ""; // This string is inserted into the [DataContract] attribute, before the closing square bracket. 187 // Example: ""; = [DataContract] 188 // "(Namespace = \"http://www.contoso.com\")"; = [DataContract(Namespace = "http://www.contoso.com")] 189 // "(Namespace = Constants.ServiceNamespace)"; = [DataContract(Namespace = Constants.ServiceNamespace)] 190 191 192 // Callbacks ********************************************************************************************************************** 193 // This method will be called right before we write the POCO header. 194 Action<Table> WritePocoClassAttributes = t => 195 { 196 // Do nothing by default 197 // Example: 198 // if(t.ClassName.StartsWith("Order")) 199 // WriteLine(" [SomeAttribute]"); 200 }; 201 202 // Writes optional base classes 203 Func<Table, string> WritePocoBaseClasses = t => 204 { 205 //if (t.ClassName == "User") 206 // return ": IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>"; 207 return ""; 208 }; 209 210 // Writes any boilerplate stuff 211 Action<Table> WritePocoBaseClassBody = t => 212 { 213 // Do nothing by default 214 // Example: 215 // WriteLine(" // " + t.ClassName); 216 }; 217 218 Func<Column, string> WritePocoColumn = c => c.Entity; 219 220 Func<StoredProcedure, string> WriteStoredProcFunctionName = sp => sp.NameHumanCase; 221 222 Func<StoredProcedure, bool, string> WriteStoredProcFunctionParams = (sp, includeProcResult) => 223 { 224 var sb = new StringBuilder(); 225 int n = 1; 226 int count = sp.Parameters.Count; 227 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 228 { 229 sb.AppendFormat("{0}{1}{2} {3}{4}", 230 p.Mode == StoredProcedureParameterMode.In ? "" : "out ", 231 p.PropertyType, 232 NotNullable.Contains(p.PropertyType.ToLower()) ? string.Empty : "?", 233 p.NameHumanCase, 234 (n++ < count) ? ", " : string.Empty); 235 } 236 if (includeProcResult && sp.ReturnModels.Count > 0 && sp.ReturnModels.First().Count > 0) 237 sb.AppendFormat((sp.Parameters.Count > 0 ? ", " : "") + "out int procResult"); 238 return sb.ToString(); 239 }; 240 241 Func<StoredProcedure, string> WriteStoredProcFunctionOverloadCall = (sp) => 242 { 243 var sb = new StringBuilder(); 244 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 245 { 246 sb.AppendFormat("{0}{1}, ", 247 p.Mode == StoredProcedureParameterMode.In ? "" : "out ", 248 p.NameHumanCase); 249 } 250 sb.Append("out procResult"); 251 return sb.ToString(); 252 }; 253 254 Func<StoredProcedure, string> WriteStoredProcFunctionSqlAtParams = sp => 255 { 256 var sb = new StringBuilder(); 257 int n = 1; 258 int count = sp.Parameters.Count; 259 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 260 { 261 sb.AppendFormat("{0}{1}{2}", 262 p.Name, 263 p.Mode == StoredProcedureParameterMode.In ? string.Empty : " OUTPUT", 264 (n++ < count) ? ", " : string.Empty); 265 } 266 return sb.ToString(); 267 }; 268 269 Func<StoredProcedureParameter, string> WriteStoredProcSqlParameterName = p => p.NameHumanCase + "Param"; 270 271 Func<StoredProcedure, string> WriteStoredProcFunctionDeclareSqlParameter = sp => 272 { 273 var sb = new StringBuilder(); 274 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 275 { 276 bool isNullable = !NotNullable.Contains(p.PropertyType.ToLower()); 277 var getValueOrDefault = isNullable ? ".GetValueOrDefault()" : string.Empty; 278 279 sb.AppendLine(string.Format(" var {0} = new System.Data.SqlClient.SqlParameter {{ ParameterName = \"{1}\", SqlDbType = System.Data.SqlDbType.{2}, Direction = System.Data.ParameterDirection.{3}{4}{5}{6}{7} }};", 280 WriteStoredProcSqlParameterName(p), 281 p.Name, 282 p.SqlDbType, 283 p.Mode == StoredProcedureParameterMode.In ? "Input" : "Output", 284 p.Mode == StoredProcedureParameterMode.In ? ", Value = " + p.NameHumanCase + getValueOrDefault : string.Empty, 285 p.MaxLength > 0 ? ", Size = " + p.MaxLength : string.Empty, 286 (p.Precision > 0 || p.Scale > 0) ? ", Precision = " + p.Precision + ", Scale = " + p.Scale : string.Empty, 287 p.PropertyType.ToLower().Contains("datatable") ? ", TypeName = \"" + p.UserDefinedTypeName + "\"" : string.Empty)); 288 289 if (p.Mode == StoredProcedureParameterMode.In) 290 { 291 sb.AppendFormat( 292 isNullable 293 ? " if (!{0}.HasValue){1} {0}Param.Value = System.DBNull.Value;{1}{1}" 294 : " if ({0}Param.Value == null){1} {0}Param.Value = System.DBNull.Value;{1}{1}", 295 p.NameHumanCase, Environment.NewLine); 296 } 297 } 298 if(sp.ReturnModels.Count < 2) 299 sb.AppendLine(" var procResultParam = new System.Data.SqlClient.SqlParameter { ParameterName = \"@procResult\", SqlDbType = System.Data.SqlDbType.Int, Direction = System.Data.ParameterDirection.Output };"); 300 return sb.ToString(); 301 }; 302 303 Func<StoredProcedure, string> WriteTableValuedFunctionDeclareSqlParameter = sp => 304 { 305 var sb = new StringBuilder(); 306 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 307 { 308 var getValueOrDefault = NotNullable.Contains(p.PropertyType.ToLower()) ? string.Empty : ".GetValueOrDefault()"; 309 310 sb.AppendLine(string.Format(" var {0}Param = new System.Data.Entity.Core.Objects.ObjectParameter(\"{1}\", {2});", 311 p.NameHumanCase, 312 p.Name.Substring(1), 313 p.Mode == StoredProcedureParameterMode.In ? p.NameHumanCase + getValueOrDefault : string.Empty)); 314 } 315 return sb.ToString(); 316 }; 317 318 Func<StoredProcedure, string> WriteStoredProcFunctionSqlParameterAnonymousArray = sp => 319 { 320 var sb = new StringBuilder(); 321 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 322 { 323 sb.Append(string.Format("{0}Param, ", p.NameHumanCase)); 324 } 325 sb.Append("procResultParam"); 326 return sb.ToString(); 327 }; 328 329 Func<StoredProcedure, string> WriteTableValuedFunctionSqlParameterAnonymousArray = sp => 330 { 331 if (sp.Parameters.Count == 0) 332 return "new System.Data.Entity.Core.Objects.ObjectParameter[] { }"; 333 var sb = new StringBuilder(); 334 foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) 335 { 336 sb.Append(string.Format("{0}Param, ", p.NameHumanCase)); 337 } 338 return sb.ToString().Substring(0, sb.Length - 2); 339 }; 340 341 Func<StoredProcedure, bool, string> WriteStoredProcFunctionSetSqlParameters = (sp, isFake) => 342 { 343 var sb = new StringBuilder(); 344 foreach (var p in sp.Parameters.Where(x => x.Mode != StoredProcedureParameterMode.In).OrderBy(x => x.Ordinal)) 345 { 346 string Default = string.Format("default({0})", p.PropertyType); 347 bool notNullable = NotNullable.Contains(p.PropertyType.ToLower()); 348 349 if(isFake) 350 sb.AppendLine(string.Format(" {0} = {1};", p.NameHumanCase, Default)); 351 else 352 { 353 sb.AppendLine(string.Format(" if (IsSqlParameterNull({0}Param))", p.NameHumanCase)); 354 sb.AppendLine(string.Format(" {0} = {1};", p.NameHumanCase, notNullable ? Default : "null")); 355 sb.AppendLine(" else"); 356 sb.AppendLine(string.Format(" {0} = ({1}) {2}Param.Value;", p.NameHumanCase, p.PropertyType, p.NameHumanCase)); 357 } 358 } 359 return sb.ToString(); 360 }; 361 362 Func<StoredProcedure, string> WriteStoredProcReturnModelName = sp => 363 StoredProcedureReturnTypes.ContainsKey(sp.NameHumanCase) 364 ? StoredProcedureReturnTypes[sp.NameHumanCase] 365 : StoredProcedureReturnTypes.ContainsKey(sp.Name) 366 ? StoredProcedureReturnTypes[sp.Name] 367 : string.Format("{0}ReturnModel", sp.NameHumanCase); 368 369 Func<DataColumn, string> WriteStoredProcReturnColumn = col => 370 string.Format("public System.{0}{1}{2} {{ get; set; }}", 371 col.DataType.Name, StoredProcedure.CheckNullable(col), col.ColumnName); 372 373 Func<StoredProcedure, string> WriteStoredProcReturnType = (sp) => 374 { 375 var returnModelCount = sp.ReturnModels.Count; 376 if (returnModelCount == 0) 377 return "int"; 378 379 var spReturnClassName = WriteStoredProcReturnModelName(sp); 380 return (returnModelCount == 1) ? string.Format("System.Collections.Generic.List<{0}>", spReturnClassName) : spReturnClassName; 381 }; 382 383 384 // That‘s it, nothing else to configure *********************************************************************************************** 385 386 387 388 // Read schema 389 var factory = GetDbProviderFactory(); 390 IsSqlCe = IsSqlCeConnection(factory); 391 var tables = LoadTables(factory); 392 var storedProcs = LoadStoredProcs(factory); 393 394 // Generate output 395 if (tables.Count > 0 || storedProcs.Count > 0) 396 { 397 #> 398 <#@ include file="EF.Reverse.POCO.ttinclude" #> 399 <#@ import namespace="System.Xml.Schema" #> 400 <# } #>
<#@ include file="EF.Reverse.POCO.Core.ttinclude" #><# // v2.18.1 // Please make changes to the settings below. // All you have to do is save this file, and the output file(s) is/are generated. Compiling does not regenerate the file(s).
// Main settings ********************************************************************************************************************** // Namespace = ""; // Override the default namespace here DbContextName = "MyDbContext"; DbContextInterfaceBaseClasses = "System.IDisposable"; // Specify what the base classes are for your database context interface DbContextBaseClass = "System.Data.Entity.DbContext"; // Specify what the base class is for your DbContext. For ASP.NET Identity use "IdentityDbContext<ApplicationUser>" ConnectionStringName = "MyDbContext"; // Searches for this connection string in config files listed below TargetFrameworkVersion = "4.51"; // Please set this to your .NET framework version, 4.0, 4.5, 4.51, etc. ConfigurationClassName = "Configuration"; // Configuration, Mapping, Map, etc. This is appended to the Poco class name to configure the mappings. ConfigFilenameSearchOrder = new[] { "app.config", "web.config", "app.config.transform", "web.config.transform" }; // Add more here if required. The config files are searched for in the local project first, then the whole solution second. MakeClassesPartial = false; GenerateSeparateFiles = false; UseCamelCase = true; // This will rename the tables & fields to use CamelCase. If false table & field names will be left alone. IncludeComments = true; // Adds comments to the generated code IncludeExtendedPropertyComments = ExtendedPropertyCommentsStyle.InSummaryBlock; // Adds extended properties as comments to the generated code IncludeViews = true; IncludeStoredProcedures = true; IncludeTableValuedFunctions = false; // If true, you must also install the "EntityFramework.CodeFirstStoreFunctions" Nuget Package. DisableGeographyTypes = false; // Turns off use of System.Data.Entity.Spatial.DbGeography and System.Data.Entity.Spatial.DbGeometry as OData doesn‘t support entities with geometry/geography types. CollectionType = "System.Collections.Generic.List"; // Determines the type of collection for the Navigation Properties. "ObservableCollection" for example. Add "System.Collections.ObjectModel" to AdditionalNamespaces if setting the CollectionType = "ObservableCollection". AddUnitTestingDbContext = true; // Will add a FakeDbContext and FakeDbSet for easy unit testing IncludeQueryTraceOn9481Flag = false; // If SqlServer 2014 appears frozen / take a long time when this file is saved, try setting this to true (you will also need elevated privileges). AdditionalNamespaces = new[] { "" }; // To include extra namespaces, include them here. i.e. "Microsoft.AspNet.Identity.EntityFramework" AdditionalContextInterfaceItems = new[] // To include extra db context interface items, include them here. Also set MakeClassesPartial=true, and implement the partial DbContext class functions. { "" // example: "void SetAutoDetectChangesEnabled(bool flag);" }; // If you need to serialize your entities with the JsonSerializer from Newtonsoft, this would serialize // all properties including the Reverse Navigation and Foreign Keys. The simplest way to exclude them is // to use the data annotation [JsonIgnore] on reverse navigation and foreign keys. AdditionalReverseNavigationsDataAnnotations = new string[] // Data Annotations for ReverseNavigationProperty. { // "JsonIgnore" }; AdditionalForeignKeysDataAnnotations = new string[] // Data Annotations for ForeignKeys. { // "JsonIgnore" };
// Migrations ************************************************************************************************************************* MigrationConfigurationFileName = ""; // null or empty to not create migrations MigrationStrategy = "MigrateDatabaseToLatestVersion"; // MigrateDatabaseToLatestVersion, CreateDatabaseIfNotExists or DropCreateDatabaseIfModelChanges ContextKey = ""; // Sets the string used to distinguish migrations belonging to this configuration from migrations belonging to other configurations using the same database. This property enables migrations from multiple different models to be applied to applied to a single database. AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; // if true, can drop fields and lose data during automatic migration
// Pluralization ********************************************************************************************************************** // To turn off pluralization, use: // Inflector.PluralizationService = null; // Default pluralization, use: // Inflector.PluralizationService = new EnglishPluralizationService(); // For Spanish pluralization: // 1. Intall the "EF6.Contrib" Nuget Package. // 2. Add the following to the top of this file and adjust path, and remove the space between the angle bracket and # at the beginning and end. // < #@ assembly name="your full path to \EntityFramework.Contrib.dll" # > // 3. Change the line below to: Inflector.PluralizationService = new SpanishPluralizationService(); Inflector.PluralizationService = new EnglishPluralizationService(new[] { // Create custom ("Singular", "Plural") forms for one-off words as needed new CustomPluralizationEntry("LiveQuiz", "LiveQuizzes"), new CustomPluralizationEntry("Course", "Courses"), new CustomPluralizationEntry("CustomerStatus", "CustomerStatus"), // Use same value to prevent pluralisation new CustomPluralizationEntry("EmployeeStatus", "EmployeeStatus") }); // Elements to generate *************************************************************************************************************** // Add the elements that should be generated when the template is executed. // Multiple projects can now be used that separate the different concerns. ElementsToGenerate = Elements.Poco | Elements.Context | Elements.UnitOfWork | Elements.PocoConfiguration;
// Use these namespaces to specify where the different elements now live. These may even be in different assemblies. // Please note this does not create the files in these locations, it only adds a using statement to say where they are. // I show how this works on the video from 26:08 onwards. // The way to do this is to add the "EntityFramework Reverse POCO Code First Generator" into each of these folders. // Then set the .tt to only generate the relevant section you need by setting // ElementsToGenerate = Elements.Poco; in your Entity folder, // ElementsToGenerate = Elements.Context | Elements.UnitOfWork; in your Context folder, // ElementsToGenerate = Elements.PocoConfiguration; in your Maps folder. // PocoNamespace = "YourProject.Entities"; // ContextNamespace = "YourProject.Context"; // UnitOfWorkNamespace = "YourProject.Context"; // PocoConfigurationNamespace = "YourProject.Maps"; // You also need to set the following to the namespace where they now live: PocoNamespace = ""; ContextNamespace = ""; UnitOfWorkNamespace = ""; PocoConfigurationNamespace = "";
// Schema ***************************************************************************************************************************** // If there are multiple schemas, then the table name is prefixed with the schema, except for dbo. // Ie. dbo.hello will be Hello. // abc.hello will be AbcHello. PrependSchemaName = true; // Control if the schema name is prepended to the table name
// Filtering ************************************************************************************************************************** // Use the following table/view name regex filters to include or exclude tables/views // Exclude filters are checked first and tables matching filters are removed. // * If left null, none are excluded. // * If not null, any tables matching the regex are excluded. // Include filters are checked second. // * If left null, all are included. // * If not null, only the tables matching the regex are included. // Example: TableFilterExclude = new Regex(".*auto.*"); // TableFilterInclude = new Regex("(.*_FR_.*)|(data_.*)"); // TableFilterInclude = new Regex("^table_name1$|^table_name2$|etc"); // ColumnFilterExclude = new Regex("^FK_.*$"); SchemaFilterExclude = null; SchemaFilterInclude = null; TableFilterExclude = null; TableFilterInclude = null; ColumnFilterExclude = null;
// Stored Procedures ****************************************************************************************************************** // Use the following regex filters to include or exclude stored procedures StoredProcedureFilterExclude = null; StoredProcedureFilterInclude = null;
// Table renaming ********************************************************************************************************************* // Use the following function to rename tables such as tblOrders to Orders, Shipments_AB to Shipments, etc. // Example: /*TableRename = (name, schema) => { if (name.StartsWith("tbl")) name = name.Remove(0, 3); return name.Replace("_AB", ""); };*/ TableRename = (name, schema) => name; // Do nothing by default // Column modification***************************************************************************************************************** // Use the following list to replace column byte types with Enums. // As long as the type can be mapped to your new type, all is well. //EnumsDefinitions.Add(new EnumDefinition { Schema = "dbo", Table = "match_table_name", Column = "match_column_name", EnumType = "name_of_enum" }); //EnumsDefinitions.Add(new EnumDefinition { Schema = "dbo", Table = "OrderHeader", Column = "OrderStatus", EnumType = "OrderStatusType" }); // This will replace OrderHeader.OrderStatus type to be an OrderStatusType enum // Use the following function if you need to apply additional modifications to a column // eg. normalise names etc. UpdateColumn = (Column column, Table table) => { // Example //if (column.NameHumanCase == "PkId") // column.NameHumanCase = "Id";
// Perform Enum property type replacement var enumDefinition = EnumsDefinitions.FirstOrDefault(e => (e.Schema.ToLowerInvariant() == table.Schema.ToLowerInvariant()) && (e.Table == table.Name || e.Table == table.NameHumanCase) && (e.Column == column.Name || e.Column == column.NameHumanCase));
if (enumDefinition != null) column.PropertyType = enumDefinition.EnumType; return column; };
// StoredProcedure renaming ************************************************************************************************************ // Use the following function to rename stored procs such as sp_CreateOrderHistory to CreateOrderHistory, my_sp_shipments to Shipments, etc. // Example: /*StoredProcedureRename = (name, schema) => { if (name.StartsWith("sp_")) name = name.Remove(0, 3); return name.Replace("my_sp_", ""); };*/ StoredProcedureRename = (name, schema) => name; // Do nothing by default
// StoredProcedure return types ******************************************************************************************************* // Override generation of return models for stored procedures that return entities. // If a stored procedure returns an entity, add it to the list below. // This will suppress the generation of the return model, and instead return the entity. // Example: Proc name Return this entity type instead //StoredProcedureReturnTypes.Add("SalesByYear", "SummaryOfSalesByYear");
// WCF ******************************************************************************************************************************** // This is only intended as a helper, to get you started creating WCF contracts, and to save a lot of typing. AddWcfDataAttributes = false; ExtraWcfDataContractAttributes = ""; // This string is inserted into the [DataContract] attribute, before the closing square bracket. // Example: ""; = [DataContract] // "(Namespace = \"http://www.contoso.com\")"; = [DataContract(Namespace = "http://www.contoso.com")] // "(Namespace = Constants.ServiceNamespace)"; = [DataContract(Namespace = Constants.ServiceNamespace)]
// Callbacks ********************************************************************************************************************** // This method will be called right before we write the POCO header. Action<Table> WritePocoClassAttributes = t => { // Do nothing by default // Example: // if(t.ClassName.StartsWith("Order")) // WriteLine(" [SomeAttribute]"); };
// Writes optional base classes Func<Table, string> WritePocoBaseClasses = t => { //if (t.ClassName == "User") // return ": IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>"; return ""; };
// Writes any boilerplate stuff Action<Table> WritePocoBaseClassBody = t => { // Do nothing by default // Example: // WriteLine(" // " + t.ClassName); };
Func<Column, string> WritePocoColumn = c => c.Entity;
Func<StoredProcedure, string> WriteStoredProcFunctionName = sp => sp.NameHumanCase;
Func<StoredProcedure, bool, string> WriteStoredProcFunctionParams = (sp, includeProcResult) => { var sb = new StringBuilder(); int n = 1; int count = sp.Parameters.Count; foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { sb.AppendFormat("{0}{1}{2} {3}{4}", p.Mode == StoredProcedureParameterMode.In ? "" : "out ", p.PropertyType, NotNullable.Contains(p.PropertyType.ToLower()) ? string.Empty : "?", p.NameHumanCase, (n++ < count) ? ", " : string.Empty); } if (includeProcResult && sp.ReturnModels.Count > 0 && sp.ReturnModels.First().Count > 0) sb.AppendFormat((sp.Parameters.Count > 0 ? ", " : "") + "out int procResult"); return sb.ToString(); }; Func<StoredProcedure, string> WriteStoredProcFunctionOverloadCall = (sp) => { var sb = new StringBuilder(); foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { sb.AppendFormat("{0}{1}, ", p.Mode == StoredProcedureParameterMode.In ? "" : "out ", p.NameHumanCase); } sb.Append("out procResult"); return sb.ToString(); };
Func<StoredProcedure, string> WriteStoredProcFunctionSqlAtParams = sp => { var sb = new StringBuilder(); int n = 1; int count = sp.Parameters.Count; foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { sb.AppendFormat("{0}{1}{2}", p.Name, p.Mode == StoredProcedureParameterMode.In ? string.Empty : " OUTPUT", (n++ < count) ? ", " : string.Empty); } return sb.ToString(); };
Func<StoredProcedureParameter, string> WriteStoredProcSqlParameterName = p => p.NameHumanCase + "Param";
Func<StoredProcedure, string> WriteStoredProcFunctionDeclareSqlParameter = sp => { var sb = new StringBuilder(); foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { bool isNullable = !NotNullable.Contains(p.PropertyType.ToLower()); var getValueOrDefault = isNullable ? ".GetValueOrDefault()" : string.Empty;
sb.AppendLine(string.Format(" var {0} = new System.Data.SqlClient.SqlParameter {{ ParameterName = \"{1}\", SqlDbType = System.Data.SqlDbType.{2}, Direction = System.Data.ParameterDirection.{3}{4}{5}{6}{7} }};", WriteStoredProcSqlParameterName(p), p.Name, p.SqlDbType, p.Mode == StoredProcedureParameterMode.In ? "Input" : "Output", p.Mode == StoredProcedureParameterMode.In ? ", Value = " + p.NameHumanCase + getValueOrDefault : string.Empty, p.MaxLength > 0 ? ", Size = " + p.MaxLength : string.Empty, (p.Precision > 0 || p.Scale > 0) ? ", Precision = " + p.Precision + ", Scale = " + p.Scale : string.Empty, p.PropertyType.ToLower().Contains("datatable") ? ", TypeName = \"" + p.UserDefinedTypeName + "\"" : string.Empty));
if (p.Mode == StoredProcedureParameterMode.In) { sb.AppendFormat( isNullable ? " if (!{0}.HasValue){1} {0}Param.Value = System.DBNull.Value;{1}{1}" : " if ({0}Param.Value == null){1} {0}Param.Value = System.DBNull.Value;{1}{1}", p.NameHumanCase, Environment.NewLine); } } if(sp.ReturnModels.Count < 2) sb.AppendLine(" var procResultParam = new System.Data.SqlClient.SqlParameter { ParameterName = \"@procResult\", SqlDbType = System.Data.SqlDbType.Int, Direction = System.Data.ParameterDirection.Output };"); return sb.ToString(); };
Func<StoredProcedure, string> WriteTableValuedFunctionDeclareSqlParameter = sp => { var sb = new StringBuilder(); foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { var getValueOrDefault = NotNullable.Contains(p.PropertyType.ToLower()) ? string.Empty : ".GetValueOrDefault()"; sb.AppendLine(string.Format(" var {0}Param = new System.Data.Entity.Core.Objects.ObjectParameter(\"{1}\", {2});", p.NameHumanCase, p.Name.Substring(1), p.Mode == StoredProcedureParameterMode.In ? p.NameHumanCase + getValueOrDefault : string.Empty)); } return sb.ToString(); };
Func<StoredProcedure, string> WriteStoredProcFunctionSqlParameterAnonymousArray = sp => { var sb = new StringBuilder(); foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { sb.Append(string.Format("{0}Param, ", p.NameHumanCase)); } sb.Append("procResultParam"); return sb.ToString(); }; Func<StoredProcedure, string> WriteTableValuedFunctionSqlParameterAnonymousArray = sp => { if (sp.Parameters.Count == 0) return "new System.Data.Entity.Core.Objects.ObjectParameter[] { }"; var sb = new StringBuilder(); foreach (var p in sp.Parameters.OrderBy(x => x.Ordinal)) { sb.Append(string.Format("{0}Param, ", p.NameHumanCase)); } return sb.ToString().Substring(0, sb.Length - 2); };
Func<StoredProcedure, bool, string> WriteStoredProcFunctionSetSqlParameters = (sp, isFake) => { var sb = new StringBuilder(); foreach (var p in sp.Parameters.Where(x => x.Mode != StoredProcedureParameterMode.In).OrderBy(x => x.Ordinal)) { string Default = string.Format("default({0})", p.PropertyType); bool notNullable = NotNullable.Contains(p.PropertyType.ToLower());
if(isFake) sb.AppendLine(string.Format(" {0} = {1};", p.NameHumanCase, Default)); else { sb.AppendLine(string.Format(" if (IsSqlParameterNull({0}Param))", p.NameHumanCase)); sb.AppendLine(string.Format(" {0} = {1};", p.NameHumanCase, notNullable ? Default : "null")); sb.AppendLine(" else"); sb.AppendLine(string.Format(" {0} = ({1}) {2}Param.Value;", p.NameHumanCase, p.PropertyType, p.NameHumanCase)); } } return sb.ToString(); };
Func<StoredProcedure, string> WriteStoredProcReturnModelName = sp => StoredProcedureReturnTypes.ContainsKey(sp.NameHumanCase) ? StoredProcedureReturnTypes[sp.NameHumanCase] : StoredProcedureReturnTypes.ContainsKey(sp.Name) ? StoredProcedureReturnTypes[sp.Name] : string.Format("{0}ReturnModel", sp.NameHumanCase);
Func<DataColumn, string> WriteStoredProcReturnColumn = col => string.Format("public System.{0}{1}{2} {{ get; set; }}", col.DataType.Name, StoredProcedure.CheckNullable(col), col.ColumnName);
Func<StoredProcedure, string> WriteStoredProcReturnType = (sp) => { var returnModelCount = sp.ReturnModels.Count; if (returnModelCount == 0) return "int";
var spReturnClassName = WriteStoredProcReturnModelName(sp); return (returnModelCount == 1) ? string.Format("System.Collections.Generic.List<{0}>", spReturnClassName) : spReturnClassName; };
// That‘s it, nothing else to configure *********************************************************************************************** // Read schema var factory = GetDbProviderFactory(); IsSqlCe = IsSqlCeConnection(factory); var tables = LoadTables(factory); var storedProcs = LoadStoredProcs(factory); // Generate output if (tables.Count > 0 || storedProcs.Count > 0) {#><#@ include file="EF.Reverse.POCO.ttinclude" #><#@ import namespace="System.Xml.Schema" #><# } #>