altair

EdmxMetadata.tt

Jun 23rd, 2011
426
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.97 KB | None | 0 0
  1. <#@ template language="C#" debug="false" hostspecific="true" #><#@ output extension=".cs" #><#@ include file="EF.Utility.CS.ttinclude"#><#
  2.  
  3. const string MODEL_FILE_NAME = @"..\Libricola.edmx";
  4. const string RESOURCE_CLASS_NAME = "Resources.ModelLocalization";
  5.  
  6. MetadataLoader loader = new MetadataLoader(this);
  7. EdmItemCollection items = loader.CreateEdmItemCollection(MODEL_FILE_NAME);
  8. CreateMetaFile(items, RESOURCE_CLASS_NAME);
  9. #>
  10. <#+
  11. void CreateMetaFile(EdmItemCollection items, string resourceTypeName){
  12.     const string ATR_METADATA = "[MetadataType(typeof({0}Metadata))]";
  13.    
  14.     // Code generation helpers
  15.     CodeGenerationTools code = new CodeGenerationTools(this);
  16.     CodeRegion region = new CodeRegion(this, 0);
  17.  
  18.     // Get namespace without last directory
  19.     var nsData = code.VsNamespaceSuggestion().Split('.');
  20.     var ns = string.Join(".", nsData, 0, nsData.Length - 1);
  21.    
  22.     // Write file header
  23.     this.WriteLine("using System;");
  24.     this.WriteLine("using System.Collections.Generic;");
  25.     this.WriteLine("using System.Collections.Specialized;");
  26.     this.WriteLine("using System.ComponentModel.DataAnnotations;");
  27.     this.WriteLine("");
  28.     this.WriteLine("namespace {0} {{", ns);
  29.     this.PushIndent("\t");
  30.     this.WriteLine("");
  31.    
  32.     foreach (EntityType entity in items.GetItems<EntityType>().OrderBy(e => e.Name)) {
  33.         // Write entity class header
  34.         this.WriteLine(ATR_METADATA, code.Escape(entity.Name));
  35.         this.WriteLine("{0} partial class {1} {{",
  36.             Accessibility.ForType(entity),  // 0
  37.             code.Escape(entity.Name));      // 1
  38.         this.WriteLine("");
  39.         this.PushIndent("\t");
  40.    
  41.         // Write metadata class header
  42.         region.Begin(string.Format("{0} metadata", entity.Name));
  43.         this.WriteLine("");
  44.         this.WriteLine("{0} class {1}Metadata {{",
  45.             Accessibility.ForType(entity),  // 0
  46.             code.Escape(entity.Name));      // 1
  47.         this.PushIndent("\t");
  48.         this.WriteLine("");
  49.    
  50.         // Process common properties
  51.         foreach (EdmMember property in entity.Properties.Where(p => p.DeclaringType == entity)) {
  52.             if(property.Name.EndsWith("Id", StringComparison.Ordinal)) continue;
  53.             ProcessMetaProperty(property, resourceTypeName);
  54.         }
  55.        
  56.         // Process navigation properties
  57.         foreach (EdmMember property in entity.NavigationProperties.Where(np => np.DeclaringType == entity)) {
  58.             ProcessMetaProperty(property, resourceTypeName);
  59.         }
  60.        
  61.         // Write metadata class footer
  62.         this.PopIndent();
  63.         this.WriteLine("}");
  64.         region.End();
  65.         this.WriteLine("");
  66.        
  67.         // Write entity class footer
  68.         this.PopIndent();
  69.         this.WriteLine("}");
  70.         this.WriteLine("");
  71.     }  
  72.    
  73.     // Write file footer
  74.     this.PopIndent();
  75.     this.WriteLine("}");
  76. }
  77.  
  78. void ProcessMetaProperty(EdmMember property, string resourceTypeName) {
  79.     const string ATR_DISPLAY_1 = "[Display(ResourceType = typeof({0}), Name = \"{1}_{2}_Name\")]";                                 
  80.     const string ATR_DISPLAY_2 = "[Display(ResourceType = typeof({0}), Name = \"{1}_{2}_Name\", Description = \"{1}_{2}_Description\")]";      
  81.     const string ATR_REQUIRED = "[Required(ErrorMessageResourceType = typeof({0}), ErrorMessageResourceName=\"{1}_{2}_Required\")]";           
  82.     const string ATR_STRLENGTH_MAX = "[StringLength({3}, ErrorMessageResourceType = typeof({0}), ErrorMessageResourceName=\"{1}_{2}_StrLength\")]";
  83.     const string ATR_STRLENGTH_FIX = "[StringLength({3}, MinimumLength={3}, ErrorMessageResourceType = typeof({0}), ErrorMessageResourceName=\"{1}_{2}_StrLength\")]"; 
  84.     const string ATR_TYPE_DATETIME ="[DataType(DataType.DateTime)]";
  85.     const string ATR_TYPE_TIME ="[DataType(DataType.Time)]";
  86.    
  87.     // Ignore primary keys
  88.     EdmProperty p = property as EdmProperty;
  89.     if(p != null){
  90.         MetadataTools ef = new MetadataTools(this);
  91.         if(ef.IsKey(p)) return;
  92.     }
  93.  
  94.     CodeGenerationTools code = new CodeGenerationTools(this);
  95.  
  96.     // DisplayAttribute
  97.     if(property.Documentation == null || string.IsNullOrEmpty(property.Documentation.LongDescription)) {
  98.         this.WriteLine(ATR_DISPLAY_1,
  99.             resourceTypeName,               // 0
  100.             property.DeclaringType.Name,    // 1
  101.             property.Name);                 // 2
  102.     } else {
  103.         this.WriteLine(ATR_DISPLAY_2,
  104.             resourceTypeName,               // 0
  105.             property.DeclaringType.Name,    // 1
  106.             property.Name);                 // 2
  107.     }
  108.    
  109.     // RequiredAttribute
  110.     if(!GetFacetValue(property.TypeUsage.Facets.SingleOrDefault(f=>f.Name.Equals("Nullable")), false)) {
  111.         this.WriteLine(ATR_REQUIRED,
  112.             resourceTypeName,               // 0
  113.             property.DeclaringType.Name,    // 1
  114.             property.Name);                 // 2
  115.     }
  116.    
  117.     // Type-specific attributes
  118.     if(property.TypeUsage.EdmType is PrimitiveType) {
  119.         switch (((PrimitiveType)property.TypeUsage.EdmType).PrimitiveTypeKind) {
  120.             case PrimitiveTypeKind.String:
  121.                 // StringLengthAttribute
  122.                 var maxLength = GetFacetValue(property.TypeUsage.Facets.SingleOrDefault(f=>f.Name.Equals("MaxLength")), int.MaxValue);
  123.                 if(maxLength != int.MaxValue) {
  124.                     var fixedLength= GetFacetValue(property.TypeUsage.Facets.SingleOrDefault(f=>f.Name.Equals("FixedLength")), false);
  125.                     if(fixedLength) {
  126.                         this.WriteLine(ATR_STRLENGTH_FIX,
  127.                             resourceTypeName,               // 0
  128.                             property.DeclaringType.Name,    // 1
  129.                             property.Name,                  // 2
  130.                             maxLength);                     // 3
  131.                     } else {
  132.                         this.WriteLine(ATR_STRLENGTH_MAX,
  133.                             resourceTypeName,               // 0
  134.                             property.DeclaringType.Name,    // 1
  135.                             property.Name,                  // 2
  136.                             maxLength);                     // 3
  137.                     }
  138.                 }
  139.                 break;
  140.             case PrimitiveTypeKind.DateTime:
  141.             case PrimitiveTypeKind.DateTimeOffset:
  142.                 this.WriteLine(ATR_TYPE_DATETIME);
  143.                 break;
  144.             case PrimitiveTypeKind.Time:
  145.                 this.WriteLine(ATR_TYPE_TIME);
  146.                 break;
  147.             case PrimitiveTypeKind.Binary:
  148.             case PrimitiveTypeKind.Boolean:
  149.             case PrimitiveTypeKind.Byte:
  150.             case PrimitiveTypeKind.Decimal:
  151.             case PrimitiveTypeKind.Double:
  152.             case PrimitiveTypeKind.Guid:
  153.             case PrimitiveTypeKind.Int16:
  154.             case PrimitiveTypeKind.Int32:
  155.             case PrimitiveTypeKind.Int64:
  156.             case PrimitiveTypeKind.SByte:
  157.             case PrimitiveTypeKind.Single:
  158.             default:
  159.                 break;
  160.         }
  161.     }
  162.    
  163.     // Property itself
  164.     this.WriteLine("{0} {1} {2} {{ get; set; }}",
  165.         Accessibility.ForProperty(property),    // 0
  166.         code.Escape(property.TypeUsage),
  167.         code.Escape(property.Name));
  168.     this.WriteLine("");
  169. }
  170.  
  171. string FormatPropertyName(string propertyName) {
  172.     var uppercaseWords = new string[] { "ID", "XML" };
  173.     var lastWasUpperCase = false;
  174.     var words = new List<string>();
  175.     var word = string.Empty;
  176.     for (int i = 0; i < propertyName.Length; i++) {
  177.         if(Char.IsUpper(propertyName[i])) {
  178.             if(!lastWasUpperCase && i > 0) {
  179.                 if(uppercaseWords.Contains(word,  StringComparer.CurrentCultureIgnoreCase)) word = word.ToUpper();
  180.                 words.Add(word);
  181.                 word = string.Empty;
  182.             }
  183.             lastWasUpperCase = true;
  184.         } else {
  185.             lastWasUpperCase = false;
  186.         }
  187.         word += propertyName[i];
  188.     }
  189.     if(uppercaseWords.Contains(word,  StringComparer.CurrentCultureIgnoreCase)) word = word.ToUpper();
  190.     words.Add(word);
  191.     return string.Join(" ", words.ToArray());
  192. }
  193.  
  194. T GetFacetValue<T>(Facet f, T defaultValue) {
  195.     if (f == null) return defaultValue;
  196.     try {          
  197.         return (T)f.Value;         
  198.     } catch {
  199.         return defaultValue;
  200.     }
  201. }
  202. #>
Advertisement
Add Comment
Please, Sign In to add comment