fork download
  1. <#
  2. // You can use this text template to customize object layer code generation for
  3. // applications that use the Entity Framework. The template generates code based on an .edmx file.
  4. // Before using this template, note the following:
  5. //
  6. // *The name of the text template file will determine the name of the code file it generates.
  7. // For example, if the text template is named TextTemplate.tt, the generated file will be named
  8. // TextTemplate.vb or TextTemplate.cs.
  9. // *The Custom Tool property of the targeted .edmx file must be empty. For more information,
  10. // see .edmx File Properties (http://go.microsoft.com/fwlink/?LinkId=139299).
  11. // *The SourceCsdlPath initialization below must be set to one of the following:
  12. // 1) the path of the targeted .edmx or .csdl file
  13. // 2) the path of the targeted .edmx or .csdl file relative to the template path
  14. //
  15. // For more detailed information about using this template, see
  16. // How to: Customize Object Layer Code Generation (http://go.microsoft.com/fwlink/?LinkId=139297).
  17. // For general information about text templates, see
  18. // Generating Artifacts by Using Text Templates (http://go.microsoft.com/fwlink/?LinkId=139298)
  19. #>
  20. <#@ template language="C#" debug="false" hostspecific="true"#>
  21. <#@ include file="EF.Utility.CS.ttinclude"#><#@
  22. output extension=".cs"#><#
  23.  
  24. var sharedNamespace="Project.Shared";
  25. var behaviorNamespace=sharedNamespace+".Behaviors";
  26. var dtoNamespace=sharedNamespace+".DataInterfaces";
  27. var mappings= new Dictionary<string,string>{{ "SourceSystem1","SourceSystem"}};
  28. ///http://d...content-available-to-author-only...s.com/2010/01/28/tracing-sql-statements-generated-by-entity-framework/
  29.  
  30. UserSettings userSettings =
  31. new UserSettings
  32. {
  33. SourceCsdlPath = @"DbModel.edmx",
  34. ReferenceCsdlPaths = new string[] {},
  35. FullyQualifySystemTypes = true,
  36. CreateContextAddToMethods = true,
  37. CamelCaseFields = false,
  38. };
  39.  
  40. ApplyUserSettings(userSettings);
  41. if(Errors.HasErrors)
  42. {
  43. return String.Empty;
  44. }
  45.  
  46. MetadataLoader loader = new MetadataLoader(this);
  47. MetadataTools ef = new MetadataTools(this);
  48. CodeRegion region = new CodeRegion(this);
  49. CodeGenerationTools code = new CodeGenerationTools(this){FullyQualifySystemTypes = userSettings.FullyQualifySystemTypes, CamelCaseFields = userSettings.CamelCaseFields};
  50.  
  51. ItemCollection = loader.CreateEdmItemCollection(SourceCsdlPath, ReferenceCsdlPaths.ToArray());
  52. ModelNamespace = loader.GetModelNamespace(SourceCsdlPath);
  53. string namespaceName = code.VsNamespaceSuggestion();
  54. UpdateObjectNamespaceMap(namespaceName);
  55.  
  56. #>
  57. //------------------------------------------------------------------------------
  58. // <auto-generated>
  59. // <#=GetResourceString("Template_GeneratedCodeCommentLine1")#>
  60. //
  61. // <#=GetResourceString("Template_GeneratedCodeCommentLine2")#>
  62. // <#=GetResourceString("Template_GeneratedCodeCommentLine3")#>
  63. // </auto-generated>
  64. //------------------------------------------------------------------------------
  65.  
  66. using System;
  67. using System.Data.Objects;
  68. using System.Data.Objects.DataClasses;
  69. using System.Data.EntityClient;
  70. using System.Collections.Generic;
  71. using System.ComponentModel;
  72. using System.Linq;
  73. using System.Linq.Expressions;
  74. using System.Xml.Serialization;
  75. using System.Runtime.Serialization;
  76.  
  77. using <#=dtoNamespace#>;
  78.  
  79. [assembly: EdmSchemaAttribute()]
  80. <#
  81. ////////
  82. //////// Write Relationship Attributes
  83. ////////
  84. region.Begin(GetResourceString("Template_RegionRelationships"));
  85. bool first = true;
  86. foreach (AssociationType association in GetSourceSchemaTypes<AssociationType>())
  87. {
  88. if (first)
  89. {
  90. WriteLine(string.Empty);
  91. first = false;
  92. }
  93. #>
  94. [assembly: EdmRelationshipAttribute("<#=association.NamespaceName#>", "<#=association.Name#>", "<#=EndName(association, 0)#>", <#=EndMultiplicity(association, 0, code)#>, typeof(<#=EscapeEndTypeName(association, 0, code)#>), "<#=EndName(association, 1)#>", <#=EndMultiplicity(association, 1, code)#>, typeof(<#=EscapeEndTypeName(association, 1, code)#>)<#=code.StringBefore(", ", association.IsForeignKey ? "true" : null)#>)]
  95. <#
  96. }
  97. region.End();
  98.  
  99. if (!String.IsNullOrEmpty(namespaceName))
  100. {
  101. #>
  102.  
  103. namespace <#=namespaceName#>
  104. {
  105. <#
  106. PushIndent(CodeRegion.GetIndent(1));
  107. }
  108.  
  109. ////////
  110. //////// Write EntityContainer and ObjectContext classes.
  111. ////////
  112.  
  113. region.Begin(GetResourceString("Template_RegionContexts"));
  114. foreach (EntityContainer container in GetSourceSchemaTypes<EntityContainer>())
  115. {
  116. #>
  117.  
  118. /// <summary>
  119. /// <#=SummaryComment(container)#>
  120. /// </summary><#=LongDescriptionCommentElement(container, region.CurrentIndentLevel)#>
  121. <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : ObjectContext
  122. <# foreach(EntityType entity in GetSourceSchemaTypes<EntityType>().OrderBy(e => e.Name))
  123. {
  124. var keys=entity.Properties.Where(p=>p.DeclaringType==entity).Cast<EdmProperty>().Where(p=>ef.IsKey(p));
  125. var keyTypes=keys.Select(k=>MultiSchemaEscape(k.TypeUsage,code)).Aggregate((s1,s2)=>s1+","+s2);
  126. #>
  127. ,<#=behaviorNamespace#>.IRepository<I<#=code.Escape(entity)#>>,<#=behaviorNamespace#>.IRepository<<#=code.Escape(entity)#>DTO,Tuple<<#=keyTypes#>>>
  128. <# }#>
  129.  
  130. {
  131.  
  132. #region <#=GetResourceString("Template_RegionConstructors")#>
  133.  
  134. /// <summary>
  135. /// <#=String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_ContextDefaultCtorComment"), container.Name, container.Name)#>
  136. /// </summary>
  137. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  138. public <#=code.Escape(container)#>() : base("name=<#=container.Name#>", "<#=container.Name#>")
  139. {
  140. <#
  141. WriteLazyLoadingEnabled(container);
  142. #>
  143. this.ContextOptions.ProxyCreationEnabled = false;
  144. OnContextCreated();
  145. }
  146.  
  147. /// <summary>
  148. /// <#=String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_ContextCommonCtorComment"), container.Name)#>
  149. /// </summary>
  150. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  151. public <#=code.Escape(container)#>(string connectionString) : base(connectionString, "<#=container.Name#>")
  152. {
  153. <#
  154. WriteLazyLoadingEnabled(container);
  155. #>
  156. this.ContextOptions.ProxyCreationEnabled = false;
  157. OnContextCreated();
  158. }
  159.  
  160. /// <summary>
  161. /// <#=String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_ContextCommonCtorComment"), container.Name)#>
  162. /// </summary>
  163. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  164. public <#=code.Escape(container)#>(EntityConnection entityConnection) : base(entityConnection, "<#=container.Name#>")
  165. {
  166. <#
  167. WriteLazyLoadingEnabled(container);
  168. #>
  169. this.ContextOptions.ProxyCreationEnabled = false;
  170. OnContextCreated();
  171. }
  172.  
  173. #endregion <#=GetResourceString("Template_RegionConstructors")#>
  174.  
  175. #region <#=GetResourceString("Template_RegionPartialMethods")#>
  176.  
  177. partial void OnContextCreated();
  178.  
  179. #endregion <#=GetResourceString("Template_RegionPartialMethods")#>
  180.  
  181. <#
  182. ////////
  183. //////// Write EntityContainer and ObjectContext ObjectSet properties.
  184. ////////
  185. region.Begin(GetResourceString("Template_RegionObjectSetProperties"));
  186. foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
  187. {
  188. VerifyEntityTypeAndSetAccessibilityCompatability(set);
  189. #>
  190.  
  191. /// <summary>
  192. /// <#=SummaryComment(set)#>
  193. /// </summary><#=LongDescriptionCommentElement(set, region.CurrentIndentLevel)#>
  194. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  195. <#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.Escape(set)#>
  196. {
  197. get
  198. {
  199. if ((<#=code.FieldName(set)#> == null))
  200. {
  201. <#=code.FieldName(set)#> = base.CreateObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>>("<#=set.Name#>");
  202. }
  203. return <#=code.FieldName(set)#>;
  204. }
  205. }
  206. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  207. private ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.FieldName(set)#>;
  208. <#
  209. }
  210. region.End(); //Object Set properties region
  211.  
  212.  
  213.  
  214. ////////
  215. //////// Write EntityContainer and ObjectContext AddTo<EntitySet> methods.
  216. ////////
  217. //////// AddTo methods are no longer necessary since the EntitySet properties return
  218. //////// an ObjectSet<T> object, which has already has an Add method.
  219. ////////
  220. //////// AddTo methods are generated here for backwards compatibility reasons only.
  221. //////// Set the CreateContextAddToMethods property of the UserSettings object to false
  222. //////// to turn off generation of the AddTo methods.
  223. ////////
  224. region.Begin(GetResourceString("Template_RegionAddToMethods"));
  225. IEnumerable<EntitySet> addToMethods = CreateContextAddToMethods.Value ? container.BaseEntitySets.OfType<EntitySet>() : Enumerable.Empty<EntitySet>();
  226. foreach (EntitySet set in addToMethods)
  227. {
  228. string parameterName = code.Escape(FixParameterName(set.ElementType.Name, code));
  229. #>
  230.  
  231. /// <summary>
  232. /// <#=String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_GenCommentAddToMethodCs"), set.Name)#>
  233. /// </summary>
  234. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  235. <#=Accessibility.ForType(set.ElementType)#> void AddTo<#=set.Name#>(<#=MultiSchemaEscape(set.ElementType, code)#> <#=parameterName#>)
  236. {
  237. base.AddObject("<#=set.Name#>", <#=parameterName#>);
  238. }
  239. <#
  240. }
  241. region.End();
  242. WriteLine("//#endregion"+ GetResourceString("Template_RegionAddToMethods"));
  243.  
  244. ////////
  245. //////// Write EntityContainer and ObjectContext Function Import methods.
  246. ////////
  247. region.Begin(GetResourceString("Template_RegionFunctionImports"));
  248. foreach (EdmFunction edmFunction in container.FunctionImports)
  249. {
  250.  
  251. IEnumerable<FunctionImportParameter> parameters = FunctionImportParameter.Create(edmFunction.Parameters, code, ef);
  252. string paramList = string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
  253. TypeUsage returnType = edmFunction.ReturnParameter == null ? null : ef.GetElementType(edmFunction.ReturnParameter.TypeUsage);
  254. #>
  255.  
  256. /// <summary>
  257. /// <#=SummaryComment(edmFunction)#>
  258. /// </summary><#=LongDescriptionCommentElement(edmFunction, region.CurrentIndentLevel)#><#=ParameterComments(parameters.Select(p => new Tuple<string, string>(p.RawFunctionParameterName, SummaryComment(p.Source))), region.CurrentIndentLevel)#>
  259. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  260. <#=code.SpaceAfter(NewModifier(edmFunction))#><#=Accessibility.ForMethod(edmFunction)#> <#=returnType == null ? "int" : "ObjectResult<" + MultiSchemaEscape(returnType, code) + ">"#> <#=code.Escape(edmFunction)#>(<#=paramList#>)
  261. {
  262. <#
  263. foreach (FunctionImportParameter parameter in parameters)
  264. {
  265. if (!parameter.NeedsLocalVariable)
  266. continue;
  267. #>
  268. ObjectParameter <#=parameter.LocalVariableName#>;
  269. if (<#=parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"#>)
  270. {
  271. <#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", <#=parameter.FunctionParameterName#>);
  272. }
  273. else
  274. {
  275. <#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", typeof(<#=parameter.RawClrTypeName#>));
  276. }
  277.  
  278. <#
  279. }
  280. #>
  281. return base.ExecuteFunction<#=returnType == null ? "" : "<" + MultiSchemaEscape(returnType, code) + ">"#>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
  282. }
  283. <#
  284. if(returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType)
  285. {
  286. #>
  287. /// <summary>
  288. /// <#=SummaryComment(edmFunction)#>
  289. /// </summary><#=LongDescriptionCommentElement(edmFunction, region.CurrentIndentLevel)#>
  290. /// <param name="mergeOption"></param><#=ParameterComments(parameters.Select(p => new Tuple<string, string>(p.RawFunctionParameterName, SummaryComment(p.Source))), region.CurrentIndentLevel)#>
  291. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  292. <#=code.SpaceAfter(NewModifier(edmFunction))#><#=Accessibility.ForMethod(edmFunction)#> <#=returnType == null ? "int" : "ObjectResult<" + MultiSchemaEscape(returnType, code) + ">"#> <#=code.Escape(edmFunction)#>(<#=code.StringAfter(paramList, ", ")#>MergeOption mergeOption)
  293. {
  294. <#
  295. foreach (FunctionImportParameter parameter in parameters)
  296. {
  297. if (!parameter.NeedsLocalVariable)
  298. continue;
  299. #>
  300. ObjectParameter <#=parameter.LocalVariableName#>;
  301. if (<#=parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"#>)
  302. {
  303. <#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", <#=parameter.FunctionParameterName#>);
  304. }
  305. else
  306. {
  307. <#=parameter.LocalVariableName#> = new ObjectParameter("<#=parameter.EsqlParameterName#>", typeof(<#=parameter.RawClrTypeName#>));
  308. }
  309.  
  310. <#
  311. }
  312. #>
  313. return base.<#=returnType == null ? "ExecuteFunction" : "ExecuteFunction<" + MultiSchemaEscape(returnType, code) + ">"#>("<#=edmFunction.Name#>", mergeOption<#=code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
  314. }
  315. <#
  316. }
  317. }
  318. region.End();
  319. #> #region IRepositories
  320.  
  321. public bool DoTrace {get{return InterceptingProvider.DoTrace;}set{InterceptingProvider.DoTrace=value;}}
  322. readonly static TypeChangeVisitor _TypeChangeVisitor = new TypeChangeVisitor(new Dictionary<Type,Type>{
  323. <# foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>().OrderBy(e => e.Name))
  324. {
  325. var typeName=MultiSchemaEscape(set.ElementType,code);
  326. var interfaceName="I"+typeName;
  327. #>
  328. {typeof(<#=interfaceName#>),typeof(<#=typeName#>)},
  329. {typeof(<#=typeName#>DTO),typeof(<#=typeName#>)},
  330. <# }#>
  331. });
  332. static bool _useExpressionWriter;
  333. #if DEBUG
  334. public static bool UseExpressionWriter{get{return _useExpressionWriter; }set{_useExpressionWriter=value;}}
  335. #endif
  336. IQueryable<T> GetInterceptor<T>(ObjectSet<T> set) where T:class
  337. {
  338. IQueryable<T> provider;
  339. #if DEBUG
  340. if(UseExpressionWriter)
  341. provider=InterceptingProvider.Intercept( new ExpressionWriter(new DebugTextWriter("Before")),
  342. set,_TypeChangeVisitor ,new ExpressionWriter(new DebugTextWriter("After")));
  343. else
  344. #endif
  345. provider=InterceptingProvider.Intercept(set,_TypeChangeVisitor );
  346.  
  347. return provider;
  348. }
  349. //foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
  350. <# foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>().OrderBy(e => e.Name))
  351. {
  352. var typeName=MultiSchemaEscape(set.ElementType,code);
  353. var interfaceName="I"+typeName;
  354. var keys=set.ElementType.Properties.Where(p=>p.DeclaringType==set.ElementType).Cast<EdmProperty>().Where(p=>ef.IsKey(p));
  355. var locator=keys
  356. .Select(p=>MultiSchemaEscape(p.TypeUsage,code)+" "+p.Name).Aggregate((s1,s2)=>s1+","+s2);
  357. Func<string,string> setKeys=t=>keys.Select((p,index)=>t+"."+p.Name+" =keys.Item"+(index+1)+";").Aggregate((s1,s2)=>s1+Environment.NewLine+s2);
  358. //Func<string,string> setKeys=t=>keys.Select(p=>t+"."+p.Name+" = "+p.Name+";").Aggregate((s1,s2)=>s1+Environment.NewLine+s2);
  359. var keyTypes=keys.Select(k=>MultiSchemaEscape(k.TypeUsage,code)).Aggregate((s1,s2)=>s1+","+s2);
  360. #>
  361. /// <summary>
  362. /// Inserts
  363. /// </summary>
  364. <#=interfaceName#> <#=behaviorNamespace#>.IRepository<<#=interfaceName#>>.Create(<#=interfaceName#> item)
  365. {
  366. var concrete=Project.Shared.SyntaxSugar.Helpers.MapOneUsingSerializer<<#=typeName#>>(item);
  367. this.AddTo<#=code.Escape(set)#>(concrete);
  368. this.SaveChanges();
  369. return concrete;
  370. }
  371. void <#=behaviorNamespace#>.IRepository<<#=interfaceName#>>.Delete(<#=interfaceName#> item)
  372. {
  373. var stub= new <#=typeName#>(){
  374.  
  375. <#
  376. foreach (EdmProperty prop in set.ElementType.Properties.Where(p => p.DeclaringType == set.ElementType).Cast<EdmProperty>()
  377. .Where(p=>ef.IsKey(p)) )
  378. { #>
  379. <#=prop.Name#> = item.<#=mappings.ContainsKey(prop.Name)?mappings[prop.Name]:prop.Name#>,
  380. <# } #>
  381. };
  382. this.<#=code.Escape(set)#>.Attach(stub);
  383. this.DeleteObject(stub);
  384. this.SaveChanges();
  385. }
  386. /// <summary>
  387. /// Create
  388. /// </summary>
  389. <#=interfaceName#> <#=behaviorNamespace#>.IRepository<<#=interfaceName#>>.Update(<#=interfaceName#> item, IEnumerable<string> propertyList)
  390. {
  391. var concrete=Project.Shared.SyntaxSugar.Helpers.MapOneUsingSerializer<<#=typeName#>>(item);
  392. var key=this.CreateEntityKey("<#=code.Escape(set)#>",concrete);
  393. ObjectStateEntry ose;
  394. if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
  395. var entity=(<#=typeName#>)ose.Entity;
  396. <#=code.Escape(set)#>.Detach(entity);
  397. }
  398. this.<#=code.Escape(set)#>.Attach(concrete);
  399. foreach(var p in propertyList)
  400. ObjectStateManager.GetObjectStateEntry(concrete).SetModifiedProperty(p);
  401. this.SaveChanges();
  402. return concrete;
  403. }
  404.  
  405.  
  406. /// <summary>
  407. /// Class to enable business logic to query a source without knowing implementation of the source
  408. /// </summary>
  409. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  410. IQueryable<<#=interfaceName#>> <#=behaviorNamespace#>.IRepository<<#=interfaceName#>>.Query()
  411. {
  412. return GetInterceptor(<#=code.Escape(set)#>);
  413.  
  414. }
  415. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  416. IEnumerable<I<#=MultiSchemaEscape(set.ElementType, code)#>> <#=behaviorNamespace#>.IRepository<I<#=MultiSchemaEscape(set.ElementType, code)#>>.Find(Expression<Func<I<#=MultiSchemaEscape(set.ElementType, code)#>,bool>> where)
  417. {
  418. return this.<#=code.Escape(set)#>.Select<<#=typeName#>,<#=interfaceName#>>(u=>u).Where(where);
  419.  
  420. }
  421. <#}#>
  422. #endregion IRepositories
  423.  
  424. }
  425.  
  426. <#
  427. }
  428. region.End();
  429. #>
  430.  
  431. <#
  432. ////////
  433. //////// Write EntityType classes.
  434. ////////
  435. region.Begin(GetResourceString("Template_RegionEntities"));
  436. foreach (EntityType entity in GetSourceSchemaTypes<EntityType>().OrderBy(e => e.Name))
  437. {
  438. #>
  439.  
  440. /// <summary>
  441. /// <#=SummaryComment(entity)#>
  442. /// </summary><#=LongDescriptionCommentElement(entity, region.CurrentIndentLevel)#>
  443. [EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name#>")]
  444. [Serializable()]
  445. [DataContractAttribute(IsReference=true)]
  446. <#
  447. foreach (EntityType subType in ItemCollection.GetItems<EntityType>().Where(b => b.BaseType == entity))
  448. {
  449. #>
  450.  
  451. [KnownTypeAttribute(typeof(<#=MultiSchemaEscape(subType, code)#>))]
  452. <#
  453. }
  454. #>
  455. <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#>
  456. : <#=BaseTypeName(entity, code)#>,
  457. <#=dtoNamespace #>.I<#=code.Escape(entity)#>
  458. {
  459. <#
  460. if (!entity.Abstract)
  461. {
  462. WriteFactoryMethod(entity, code);
  463. }
  464.  
  465. region.Begin(GetResourceString("Template_RegionPrimitiveProperties"));
  466. foreach (EdmProperty property in entity.Properties.Where(p => p.DeclaringType == entity && p.TypeUsage.EdmType is PrimitiveType))
  467. {
  468. VerifyGetterAndSetterAccessibilityCompatability(property);
  469. WritePrimitiveTypeProperty(property, code);
  470. }
  471. region.End();
  472.  
  473. region.Begin(GetResourceString("Template_RegionComplexProperties"));
  474. foreach (EdmProperty property in entity.Properties.Where(p => p.DeclaringType == entity && p.TypeUsage.EdmType is ComplexType))
  475. {
  476. VerifyGetterAndSetterAccessibilityCompatability(property);
  477. WriteComplexTypeProperty(property, code);
  478. }
  479. region.End();
  480. #>
  481.  
  482. <#
  483. ////////
  484. //////// Write Navigation Properties.
  485. ////////
  486. region.Begin(GetResourceString("Template_RegionNavigationProperties"));
  487. foreach (NavigationProperty navProperty in entity.NavigationProperties.Where(n => n.DeclaringType == entity))
  488. {
  489. VerifyGetterAndSetterAccessibilityCompatability(navProperty);
  490. #>
  491.  
  492. /// <summary>
  493. /// <#=SummaryComment(navProperty)#>
  494. /// </summary><#=LongDescriptionCommentElement(navProperty, region.CurrentIndentLevel)#>
  495. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  496. [XmlIgnoreAttribute()]
  497. [SoapIgnoreAttribute()]
  498. [DataMemberAttribute()]
  499. [EdmRelationshipNavigationPropertyAttribute("<#=navProperty.RelationshipType.NamespaceName#>", "<#=navProperty.RelationshipType.Name#>", "<#=navProperty.ToEndMember.Name#>")]
  500. <#
  501. if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
  502. {
  503. #>
  504. <#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> EntityCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> <#=code.Escape(navProperty)#>
  505. {
  506. <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
  507. {
  508. return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>");
  509. }
  510. <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
  511. {
  512. if ((value != null))
  513. {
  514. ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>", value);
  515. }
  516. }
  517. }
  518. <#
  519. }
  520. else
  521. {
  522. #>
  523. <#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> <#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#> <#=code.Escape(navProperty)#>
  524. {
  525. <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
  526. {
  527. return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value;
  528. }
  529. <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
  530. {
  531. ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value = value;
  532. }
  533. }
  534. <#
  535. string refPropertyName = navProperty.Name + "Reference";
  536. if (entity.Members.Any(m => m.Name == refPropertyName))
  537. {
  538. // 6017 is the same error number that EntityClassGenerator uses.
  539. Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6017", String.Format(CultureInfo.CurrentCulture,
  540. GetResourceString("Template_ConflictingGeneratedNavPropName"),
  541. navProperty.Name, entity.FullName, refPropertyName)));
  542. }
  543. #>
  544. /// <summary>
  545. /// <#=SummaryComment(navProperty)#>
  546. /// </summary><#=LongDescriptionCommentElement(navProperty, region.CurrentIndentLevel)#>
  547. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  548. [BrowsableAttribute(false)]
  549. [DataMemberAttribute()]
  550. <#=Accessibility.ForProperty(navProperty)#> EntityReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>> <#=refPropertyName#>
  551. {
  552. <#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
  553. {
  554. return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>");
  555. }
  556. <#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
  557. {
  558. if ((value != null))
  559. {
  560. ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>", value);
  561. }
  562. }
  563. }
  564. <#
  565. }
  566. }
  567. region.End();
  568. #>
  569. }
  570. <# }
  571. region.End();
  572.  
  573. ////////
  574. //////// Write ComplexType classes.
  575. ////////
  576. region.Begin(GetResourceString("Template_RegionComplexTypes"));
  577. foreach (ComplexType complex in GetSourceSchemaTypes<ComplexType>().OrderBy(c => c.Name))
  578. {
  579. #>
  580. //Complex
  581. /// <summary>
  582. /// <#=SummaryComment(complex)#>
  583. /// </summary><#=LongDescriptionCommentElement(complex, region.CurrentIndentLevel)#>
  584. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  585. [EdmComplexTypeAttribute(NamespaceName="<#=complex.NamespaceName#>", Name="<#=complex.Name#>")]
  586. [DataContractAttribute(IsReference=true)]
  587. [Serializable()]
  588. <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> : ComplexObject
  589. {
  590. <#
  591. WriteFactoryMethod(complex, code);
  592. region.Begin(GetResourceString("Template_RegionPrimitiveProperties"));
  593. foreach (EdmProperty property in complex.Properties.Where(p => p.DeclaringType == complex && p.TypeUsage.EdmType is PrimitiveType))
  594. {
  595. VerifyGetterAndSetterAccessibilityCompatability(property);
  596. WritePrimitiveTypeProperty(property, code);
  597. }
  598. region.End();
  599. region.Begin(GetResourceString("Template_RegionComplexProperties"));
  600. foreach (EdmProperty property in complex.Properties.Where(p => p.DeclaringType == complex && p.TypeUsage.EdmType is ComplexType))
  601. {
  602. VerifyGetterAndSetterAccessibilityCompatability(property);
  603. WriteComplexTypeProperty(property, code);
  604. }
  605. region.End();
  606. #>
  607. }
  608. <#
  609. }
  610. region.End();
  611. #>
  612.  
  613. <#
  614. if (!String.IsNullOrEmpty(namespaceName))
  615. {
  616. PopIndent();
  617. #>
  618. }
  619. <#
  620. }
  621. VerifyTypeUniqueness();
  622. #>
  623.  
  624. <#+
  625.  
  626. ////////
  627. //////// Reusable Template Sections
  628. ////////
  629.  
  630. ////////
  631. //////// Write Factory Method.
  632. ////////
  633. private void WriteFactoryMethod(StructuralType structuralType, CodeGenerationTools code)
  634. {
  635. CodeRegion region = new CodeRegion(this, 1);
  636.  
  637. string methodName = "Create" + structuralType.Name;
  638. UniqueIdentifierService uniqueIdentifier = new UniqueIdentifierService();
  639. string instanceName = code.Escape(uniqueIdentifier.AdjustIdentifier((code.CamelCase(structuralType.Name))));
  640. IEnumerable<FactoryMethodParameter> parameters = FactoryMethodParameter.CreateParameters(structuralType.Members.OfType<EdmProperty>().Where(p => IncludePropertyInFactoryMethod(structuralType, p)), uniqueIdentifier, MultiSchemaEscape, code);
  641.  
  642. if (parameters.Count() == 0)
  643. return;
  644.  
  645. if (structuralType.Members.Any(m => m.Name == methodName))
  646. {
  647. // 6029 is the same error number that EntityClassGenerator uses for this conflict.
  648. Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6029",
  649. String.Format(CultureInfo.CurrentCulture,
  650. GetResourceString("Template_FactoryMethodNameConflict"), methodName, structuralType.FullName)));
  651. }
  652.  
  653. region.Begin(GetResourceString("Template_RegionFactoryMethod"));
  654. #>
  655.  
  656. /// <summary>
  657. /// <#=String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_FactoryMethodComment"), structuralType.Name)#>
  658. /// </summary><#=ParameterComments(parameters.Select(p => new Tuple<string, string>(p.RawParameterName, p.ParameterComment)), region.CurrentIndentLevel)#>
  659. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  660. public static <#=code.Escape(structuralType)#> <#=methodName#>(<#=string.Join(", ", parameters.Select(p => p.ParameterType + " " + p.ParameterName).ToArray())#>)
  661. {
  662. <#=code.Escape(structuralType)#> <#=instanceName#> = new <#=code.Escape(structuralType)#>();
  663. <#+
  664. foreach (FactoryMethodParameter parameter in parameters)
  665. {
  666. if (parameter.IsComplexType)
  667. {
  668. // ComplexType initialization.
  669. #>
  670. <#=instanceName#>.<#=code.Escape(parameter.Source)#> = StructuralObject.VerifyComplexObjectIsNotNull(<#=parameter.ParameterName#>, "<#=parameter.Source.Name#>");
  671. <#+
  672. }
  673. else
  674. {
  675. // PrimitiveType initialization.
  676. #>
  677. <#=instanceName#>.<#=code.Escape(parameter.Source)#> = <#=parameter.ParameterName#>;
  678. <#+
  679. }
  680. }
  681. #>
  682. return <#=instanceName#>;
  683. }
  684. <#+
  685. region.End();
  686. }
  687.  
  688.  
  689. ////////
  690. //////// Write PrimitiveType Properties.
  691. ////////
  692. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  693. private void WritePrimitiveTypeProperty(EdmProperty primitiveProperty, CodeGenerationTools code)
  694. {
  695. MetadataTools ef = new MetadataTools(this);
  696. #>
  697.  
  698. /// <summary>
  699. /// <#=SummaryComment(primitiveProperty)#>
  700. /// </summary><#=LongDescriptionCommentElement(primitiveProperty, 1)#>
  701. [EdmScalarPropertyAttribute(EntityKeyProperty=<#=code.CreateLiteral(ef.IsKey(primitiveProperty))#>, IsNullable=<#=code.CreateLiteral(ef.IsNullable(primitiveProperty))#>)]
  702. [DataMemberAttribute()]
  703. [System.CodeDom.Compiler.GeneratedCode("T4","1.0.0.0")]
  704. <#=code.SpaceAfter(NewModifier(primitiveProperty))#><#=Accessibility.ForProperty(primitiveProperty)#> <#=code.Escape(primitiveProperty.TypeUsage)#> <#=code.Escape(primitiveProperty)#>
  705. {
  706. <#=code.SpaceAfter(Accessibility.ForGetter(primitiveProperty))#>get
  707. {
  708. <#+ if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
  709. {
  710. #>
  711. return StructuralObject.GetValidValue(<#=code.FieldName(primitiveProperty)#>);
  712. <#+
  713. }
  714. else
  715. {
  716. #>
  717. return <#=code.FieldName(primitiveProperty)#>;
  718. <#+
  719. }
  720. #>
  721. }
  722. <#=code.SpaceAfter(Accessibility.ForSetter((primitiveProperty)))#>set
  723. {
  724. <#+
  725. if (ef.IsKey(primitiveProperty))
  726. {
  727. if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
  728. {
  729. #>
  730. if (!StructuralObject.BinaryEquals(<#=code.FieldName(primitiveProperty)#>, value))
  731. <#+
  732. }
  733. else
  734. {
  735. #>
  736. if (<#=code.FieldName(primitiveProperty)#> != value)
  737. <#+
  738. }
  739. #>
  740. {
  741. <#+
  742. PushIndent(CodeRegion.GetIndent(1));
  743. }
  744. #>
  745. if(<#=code.FieldName(primitiveProperty)#> != value){
  746. <#=ChangingMethodName(primitiveProperty)#>(value);
  747. ReportPropertyChanging("<#=primitiveProperty.Name#>");
  748. <#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
  749. ReportPropertyChanged("<#=primitiveProperty.Name#>");
  750. <#=ChangedMethodName(primitiveProperty)#>();
  751. }
  752. <#+
  753. if (ef.IsKey(primitiveProperty))
  754. {
  755. PopIndent();
  756. #>
  757. }
  758. <#+
  759. }
  760. #>
  761. }
  762. }
  763. private <#=code.Escape(primitiveProperty.TypeUsage)#> <#=code.FieldName(primitiveProperty)#><#=code.StringBefore(" = ", code.CreateLiteral(primitiveProperty.DefaultValue))#>;
  764. partial void <#=ChangingMethodName(primitiveProperty)#>(<#=code.Escape(primitiveProperty.TypeUsage)#> value);
  765. partial void <#=ChangedMethodName(primitiveProperty)#>();
  766. <#+
  767. }
  768.  
  769. ////////
  770. //////// Write ComplexType Properties.
  771. ////////
  772. private void WriteComplexTypeProperty(EdmProperty complexProperty, CodeGenerationTools code)
  773. {
  774. #>
  775.  
  776. /// <summary>
  777. /// <#=SummaryComment(complexProperty)#>
  778. /// </summary><#=LongDescriptionCommentElement(complexProperty, 1)#>
  779. [EdmComplexPropertyAttribute()]
  780. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  781. [XmlElement(IsNullable=true)]
  782. [SoapElement(IsNullable=true)]
  783. [DataMemberAttribute()]
  784. <#=code.SpaceAfter(NewModifier(complexProperty))#><#=Accessibility.ForProperty(complexProperty)#> <#=MultiSchemaEscape(complexProperty.TypeUsage, code)#> <#=code.Escape(complexProperty)#>
  785. {
  786. <#=code.SpaceAfter(Accessibility.ForGetter(complexProperty))#>get
  787. {
  788. <#=code.FieldName(complexProperty)#> = GetValidValue(<#=code.FieldName(complexProperty)#>, "<#=complexProperty.Name#>", false, <#=InitializedTrackingField(complexProperty, code)#>);
  789. <#=InitializedTrackingField(complexProperty, code)#> = true;
  790. return <#=code.FieldName(complexProperty)#>;
  791. }
  792. <#=code.SpaceAfter(Accessibility.ForSetter(complexProperty))#>set
  793. {
  794. <#=ChangingMethodName(complexProperty)#>(value);
  795. ReportPropertyChanging("<#=complexProperty.Name#>");
  796. <#=code.FieldName(complexProperty)#> = SetValidValue(<#=code.FieldName(complexProperty)#>, value, "<#=complexProperty.Name#>");
  797. <#=InitializedTrackingField(complexProperty, code)#> = true;
  798. ReportPropertyChanged("<#=complexProperty.Name#>");
  799. <#=ChangedMethodName(complexProperty)#>();
  800. }
  801. }
  802. private <#=MultiSchemaEscape(complexProperty.TypeUsage, code)#> <#=code.FieldName(complexProperty)#>;
  803. private bool <#=InitializedTrackingField(complexProperty, code)#>;
  804. partial void <#=ChangingMethodName(complexProperty)#>(<#=MultiSchemaEscape(complexProperty.TypeUsage, code)#> value);
  805. partial void <#=ChangedMethodName(complexProperty)#>();
  806. <#+
  807. }
  808.  
  809. private void WriteLazyLoadingEnabled(EntityContainer container)
  810. {
  811. string lazyLoadingAttributeValue = null;
  812. string lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
  813. if(MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue))
  814. {
  815. bool isLazyLoading = false;
  816. if(bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading))
  817. {
  818. #>
  819. this.ContextOptions.LazyLoadingEnabled = <#=isLazyLoading.ToString().ToLowerInvariant()#>;
  820. <#+
  821. }
  822. }
  823. }
  824.  
  825. ////////
  826. //////// Declare Template Public Properties.
  827. ////////
  828. public string SourceCsdlPath{ get; set; }
  829. public string ModelNamespace{ get; set; }
  830. public EdmItemCollection ItemCollection{ get; set; }
  831. public IEnumerable<string> ReferenceCsdlPaths{ get; set; }
  832. public Nullable<bool> CreateContextAddToMethods{ get; set; }
  833. public Dictionary<string, string> EdmToObjectNamespaceMap
  834. {
  835. get { return _edmToObjectNamespaceMap; }
  836. set { _edmToObjectNamespaceMap = value; }
  837. }
  838. public Dictionary<string, string> _edmToObjectNamespaceMap = new Dictionary<string, string>();
  839. public Double SourceEdmVersion
  840. {
  841. get
  842. {
  843. if (ItemCollection != null)
  844. {
  845. return ItemCollection.EdmVersion;
  846. }
  847.  
  848. return 0.0;
  849. }
  850. }
  851.  
  852. ////////
  853. //////// Declare Template Private Properties.
  854. ////////
  855. static System.Resources.ResourceManager ResourceManager
  856. {
  857. get
  858. {
  859. if (_resourceManager == null)
  860. {
  861. System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly);
  862. System.Threading.Interlocked.CompareExchange(ref _resourceManager, resourceManager, null);
  863. }
  864. return _resourceManager;
  865. }
  866. }
  867. static System.Resources.ResourceManager _resourceManager;
  868.  
  869. #>
  870. <#+
  871.  
  872.  
  873. private static string GetResourceString(string resourceName)
  874. {
  875. return ResourceManager.GetString(resourceName,
  876. null); // Take default culture.
  877. }
  878.  
  879.  
  880.  
  881. private void VerifyTypeUniqueness()
  882. {
  883. HashSet<string> hash = new HashSet<string>();
  884. IEnumerable<GlobalItem> allTypes = GetSourceSchemaTypes<GlobalItem>().Where(i => i is StructuralType || i is EntityContainer);
  885.  
  886. foreach (GlobalItem type in allTypes)
  887. {
  888. if (!hash.Add(GetGlobalItemName(type)))
  889. {
  890. // 6034 is the error number used by System.Data.Entity.Design EntityClassGenerator.
  891. Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6034",
  892. String.Format(CultureInfo.CurrentCulture,
  893. GetResourceString("Template_DuplicateTopLevelType"),
  894. GetGlobalItemName(type))));
  895. }
  896. }
  897. }
  898.  
  899. protected string GetGlobalItemName(GlobalItem item)
  900. {
  901. if (item is EdmType)
  902. {
  903. // EntityType or ComplexType.
  904. return ((EdmType)item).Name;
  905. }
  906. else
  907. {
  908. // Must be an EntityContainer.
  909. return ((EntityContainer)item).Name;
  910. }
  911. }
  912.  
  913.  
  914.  
  915. void ApplyUserSettings(UserSettings userSettings)
  916. {
  917. // Setup template UserSettings.
  918. if (SourceCsdlPath == null)
  919. {
  920. #if !PREPROCESSED_TEMPLATE
  921. if(userSettings.SourceCsdlPath == "$" + "edmxInputFile" + "$")
  922. {
  923. Errors.Add(new System.CodeDom.Compiler.CompilerError(Host.TemplateFile, 0, 0, "",
  924. GetResourceString("Template_ReplaceVsItemTemplateToken")));
  925. return;
  926. }
  927.  
  928. SourceCsdlPath = Host.ResolvePath(userSettings.SourceCsdlPath);
  929. #else
  930. SourceCsdlPath = userSettings.SourceCsdlPath;
  931. #endif
  932. }
  933.  
  934. // normalize the path, remove ..\ from it
  935. SourceCsdlPath = Path.GetFullPath(SourceCsdlPath);
  936.  
  937.  
  938. if (ReferenceCsdlPaths == null)
  939. {
  940. ReferenceCsdlPaths = userSettings.ReferenceCsdlPaths;
  941. }
  942.  
  943. if (!CreateContextAddToMethods.HasValue)
  944. {
  945. CreateContextAddToMethods = userSettings.CreateContextAddToMethods;
  946. }
  947.  
  948. DefaultSummaryComment = GetResourceString("Template_CommentNoDocumentation");
  949. }
  950.  
  951.  
  952. class UserSettings
  953. {
  954. public string SourceCsdlPath{ get; set; }
  955. public string[] ReferenceCsdlPaths{ get; set; }
  956. public bool FullyQualifySystemTypes{ get; set; }
  957. public bool CreateContextAddToMethods{ get; set; }
  958. public bool CamelCaseFields{ get; set; }
  959. }
  960.  
  961. string MultiSchemaEscape(TypeUsage usage, CodeGenerationTools code)
  962. {
  963. StructuralType structural = usage.EdmType as StructuralType;
  964. if (structural != null)
  965. {
  966. return MultiSchemaEscape(structural, code);
  967. }
  968. return code.Escape(usage);
  969. }
  970.  
  971. string MultiSchemaEscape(StructuralType type, CodeGenerationTools code)
  972. {
  973. if (type.NamespaceName != ModelNamespace)
  974. {
  975. return code.CreateFullName(code.EscapeNamespace(GetObjectNamespace(type.NamespaceName)), code.Escape(type));
  976. }
  977.  
  978. return code.Escape(type);
  979. }
  980.  
  981. string NewModifier(NavigationProperty navigationProperty)
  982. {
  983. Type baseType = typeof(EntityObject);
  984. return NewModifier(baseType, navigationProperty.Name);
  985. }
  986.  
  987. string NewModifier(EdmFunction edmFunction)
  988. {
  989. Type baseType = typeof(ObjectContext);
  990. return NewModifier(baseType, edmFunction.Name);
  991. }
  992.  
  993. string NewModifier(EntitySet set)
  994. {
  995. Type baseType = typeof(ObjectContext);
  996. return NewModifier(baseType, set.Name);
  997. }
  998.  
  999. string NewModifier(EdmProperty property)
  1000. {
  1001. Type baseType;
  1002. if (property.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType)
  1003. {
  1004. baseType = typeof(EntityObject);
  1005. }
  1006. else
  1007. {
  1008. baseType = typeof(ComplexObject);
  1009. }
  1010. return NewModifier(baseType, property.Name);
  1011. }
  1012.  
  1013. string NewModifier(Type type, string memberName)
  1014. {
  1015. if (HasBaseMemberWithMatchingName(type, memberName))
  1016. {
  1017. return "new";
  1018. }
  1019. return string.Empty;
  1020. }
  1021.  
  1022. static bool HasBaseMemberWithMatchingName(Type type, string memberName)
  1023. {
  1024. BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public
  1025. | BindingFlags.Instance | BindingFlags.Static;
  1026. return type.GetMembers(bindingFlags).Where(m => IsVisibleMember(m)).Any(m => m.Name == memberName);
  1027. }
  1028.  
  1029. string ChangingMethodName(EdmMember member)
  1030. {
  1031. return string.Format(CultureInfo.InvariantCulture, "On{0}Changing", member.Name);
  1032. }
  1033.  
  1034. string ChangedMethodName(EdmMember member)
  1035. {
  1036. return string.Format(CultureInfo.InvariantCulture, "On{0}Changed", member.Name);
  1037. }
  1038.  
  1039. string InitializedTrackingField(EdmProperty property, CodeGenerationTools code)
  1040. {
  1041. string namePart = property.Name + "Initialized";
  1042. if (code.CamelCaseFields)
  1043. {
  1044. namePart = code.CamelCase(namePart);
  1045. }
  1046. return "_" + namePart;
  1047. }
  1048.  
  1049. string OptionalNullableParameterForSetValidValue(EdmMember member, CodeGenerationTools code)
  1050. {
  1051. MetadataTools ef = new MetadataTools(this);
  1052. string list = string.Empty;
  1053. if (((PrimitiveType)member.TypeUsage.EdmType).ClrEquivalentType.IsClass)
  1054. {
  1055. MetadataProperty storeGeneratedPatternProperty = null;
  1056. bool isNullable = ef.IsNullable(member.TypeUsage) ||
  1057. (member.MetadataProperties.TryGetValue(MetadataConstants.EDM_ANNOTATION_09_02 + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty) &&
  1058. Object.Equals(storeGeneratedPatternProperty.Value, "Computed"));
  1059. list += ", " + code.CreateLiteral(isNullable);
  1060. }
  1061. return list;
  1062. }
  1063.  
  1064. static bool IsVisibleMember(MemberInfo memberInfo)
  1065. {
  1066. if (memberInfo is EventInfo)
  1067. {
  1068. EventInfo ei = (EventInfo)memberInfo;
  1069. MethodInfo add = ei.GetAddMethod();
  1070. MethodInfo remove = ei.GetRemoveMethod();
  1071. return IsVisibleMethod(add) || IsVisibleMethod(remove);
  1072. }
  1073. else if (memberInfo is FieldInfo)
  1074. {
  1075. FieldInfo fi = (FieldInfo)memberInfo;
  1076. return !fi.IsPrivate && !fi.IsAssembly;
  1077. }
  1078. else if (memberInfo is MethodBase)
  1079. {
  1080. MethodBase mb = (MethodBase)memberInfo;
  1081. if (mb.IsSpecialName)
  1082. return false;
  1083. return IsVisibleMethod(mb);
  1084. }
  1085. else if (memberInfo is PropertyInfo)
  1086. {
  1087. PropertyInfo pi = (PropertyInfo)memberInfo;
  1088. MethodInfo get = pi.GetGetMethod();
  1089. MethodInfo set = pi.GetSetMethod();
  1090. return IsVisibleMethod(get) || IsVisibleMethod(set);
  1091. }
  1092.  
  1093. return false;
  1094. }
  1095.  
  1096. static bool IsVisibleMethod(MethodBase methodBase)
  1097. {
  1098. if (methodBase == null)
  1099. return false;
  1100.  
  1101. return !methodBase.IsPrivate && !methodBase.IsAssembly;
  1102. }
  1103.  
  1104. IEnumerable<T> GetSourceSchemaTypes<T>() where T : GlobalItem
  1105. {
  1106. if (Path.GetExtension(SourceCsdlPath) != ".edmx")
  1107. {
  1108. return ItemCollection.GetItems<T>().Where(e => e.MetadataProperties.Any(mp => mp.Name == "SchemaSource" && (string)mp.Value == SourceCsdlPath));
  1109. }
  1110. else
  1111. {
  1112. return ItemCollection.GetItems<T>();
  1113. }
  1114. }
  1115.  
  1116. string EndName(AssociationType association, int index)
  1117. {
  1118. return association.AssociationEndMembers[index].Name;
  1119. }
  1120.  
  1121. string EndMultiplicity(AssociationType association, int index, CodeGenerationTools code)
  1122. {
  1123. return code.CreateLiteral(association.AssociationEndMembers[index].RelationshipMultiplicity);
  1124. }
  1125.  
  1126. string EscapeEndTypeName(AssociationType association, int index, CodeGenerationTools code)
  1127. {
  1128. EntityType entity = association.AssociationEndMembers[index].GetEntityType();
  1129. return code.CreateFullName(code.EscapeNamespace(GetObjectNamespace(entity.NamespaceName)), code.Escape(entity));
  1130. }
  1131.  
  1132. string GetObjectNamespace(string csdlNamespaceName)
  1133. {
  1134. string objectNamespace;
  1135. if (EdmToObjectNamespaceMap.TryGetValue(csdlNamespaceName, out objectNamespace))
  1136. {
  1137. return objectNamespace;
  1138. }
  1139.  
  1140. return csdlNamespaceName;
  1141. }
  1142.  
  1143. void UpdateObjectNamespaceMap(string objectNamespace)
  1144. {
  1145. if(objectNamespace != ModelNamespace && !EdmToObjectNamespaceMap.ContainsKey(ModelNamespace))
  1146. {
  1147. EdmToObjectNamespaceMap.Add(ModelNamespace, objectNamespace);
  1148. }
  1149. }
  1150.  
  1151. static string FixParameterName(string name, CodeGenerationTools code)
  1152. {
  1153. // Change any property that is 'id' (case insensitive) to 'ID'
  1154. // since 'iD' is a violation of FxCop rules.
  1155. if (StringComparer.OrdinalIgnoreCase.Equals(name, "id"))
  1156. {
  1157. // Return all lower case since it is an abbreviation, not an acronym.
  1158. return "id";
  1159. }
  1160. return code.CamelCase(name);
  1161. }
  1162.  
  1163. string BaseTypeName(EntityType entity, CodeGenerationTools code)
  1164. {
  1165. return entity.BaseType == null ? "EntityObject" : MultiSchemaEscape((StructuralType)entity.BaseType, code);
  1166. }
  1167.  
  1168. bool IncludePropertyInFactoryMethod(StructuralType factoryType, EdmProperty edmProperty)
  1169. {
  1170. if (edmProperty.Nullable)
  1171. {
  1172. return false;
  1173. }
  1174.  
  1175. if (edmProperty.DefaultValue != null)
  1176. {
  1177. return false;
  1178. }
  1179.  
  1180. if ((Accessibility.ForReadOnlyProperty(edmProperty) != "public" && Accessibility.ForWriteOnlyProperty(edmProperty) != "public") ||
  1181. (factoryType != edmProperty.DeclaringType && Accessibility.ForWriteOnlyProperty(edmProperty) == "private")
  1182. )
  1183. {
  1184. // There is no public part to the property.
  1185. return false;
  1186. }
  1187.  
  1188. return true;
  1189. }
  1190.  
  1191.  
  1192. class FactoryMethodParameter
  1193. {
  1194. public EdmProperty Source;
  1195. public string RawParameterName;
  1196. public string ParameterName;
  1197. public string ParameterType;
  1198. public string ParameterComment;
  1199. public bool IsComplexType;
  1200.  
  1201. public static IEnumerable<FactoryMethodParameter> CreateParameters(IEnumerable<EdmProperty> properties, UniqueIdentifierService unique, Func<TypeUsage, CodeGenerationTools, string> multiSchemaEscape, CodeGenerationTools code)
  1202. {
  1203. List<FactoryMethodParameter> parameters = new List<FactoryMethodParameter>();
  1204. foreach (EdmProperty property in properties)
  1205. {
  1206. FactoryMethodParameter parameter = new FactoryMethodParameter();
  1207. parameter.Source = property;
  1208. parameter.IsComplexType = property.TypeUsage.EdmType is ComplexType;
  1209. parameter.RawParameterName = unique.AdjustIdentifier(FixParameterName(property.Name, code));
  1210. parameter.ParameterName = code.Escape(parameter.RawParameterName);
  1211. parameter.ParameterType = multiSchemaEscape(property.TypeUsage, code);
  1212. parameter.ParameterComment = String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CommentFactoryMethodParam"), property.Name);
  1213. parameters.Add(parameter);
  1214. }
  1215.  
  1216. return parameters;
  1217. }
  1218. }
  1219.  
  1220. string DefaultSummaryComment{ get; set; }
  1221.  
  1222. string SummaryComment(MetadataItem item)
  1223. {
  1224. if (item.Documentation != null && item.Documentation.Summary != null)
  1225. {
  1226. return PrefixLinesOfMultilineComment(XMLCOMMENT_START + " ", XmlEntityize(item.Documentation.Summary));
  1227. }
  1228.  
  1229. if (DefaultSummaryComment != null)
  1230. {
  1231. return DefaultSummaryComment;
  1232. }
  1233.  
  1234. return string.Empty;
  1235. }
  1236.  
  1237. string LongDescriptionCommentElement(MetadataItem item, int indentLevel)
  1238. {
  1239. if (item.Documentation != null && !String.IsNullOrEmpty(item.Documentation.LongDescription))
  1240. {
  1241. string comment = Environment.NewLine;
  1242. string lineStart = CodeRegion.GetIndent(indentLevel) + XMLCOMMENT_START + " ";
  1243. comment += lineStart + "<LongDescription>" + Environment.NewLine;
  1244. comment += lineStart + PrefixLinesOfMultilineComment(lineStart, XmlEntityize(item.Documentation.LongDescription)) + Environment.NewLine;
  1245. comment += lineStart + "</LongDescription>";
  1246. return comment;
  1247. }
  1248. return string.Empty;
  1249. }
  1250.  
  1251. string PrefixLinesOfMultilineComment(string prefix, string comment)
  1252. {
  1253. return comment.Replace(Environment.NewLine, Environment.NewLine + prefix);
  1254. }
  1255.  
  1256. string ParameterComments(IEnumerable<Tuple<string, string>> parameters, int indentLevel)
  1257. {
  1258. System.Text.StringBuilder builder = new System.Text.StringBuilder();
  1259. foreach (Tuple<string, string> parameter in parameters)
  1260. {
  1261. builder.AppendLine();
  1262. builder.Append(CodeRegion.GetIndent(indentLevel));
  1263. builder.Append(XMLCOMMENT_START);
  1264. builder.Append(String.Format(CultureInfo.InvariantCulture, " <param name=\"{0}\">{1}</param>", parameter.Item1, parameter.Item2));
  1265. }
  1266. return builder.ToString();
  1267. }
  1268.  
  1269. string XmlEntityize(string text)
  1270. {
  1271. if (string.IsNullOrEmpty(text))
  1272. {
  1273. return string.Empty;
  1274. }
  1275.  
  1276. text = text.Replace("&","&amp;");
  1277. text = text.Replace("<","&lt;").Replace(">","&gt;");
  1278. string id = Guid.NewGuid().ToString();
  1279. text = text.Replace(Environment.NewLine, id);
  1280. text = text.Replace("\r", "&#xD;").Replace("\n","&#xA;");
  1281. text = text.Replace(id, Environment.NewLine);
  1282. return text.Replace("\'","&apos;").Replace("\"","&quot;");
  1283. }
  1284.  
  1285. const string XMLCOMMENT_START = "///";
  1286. IEnumerable<EdmProperty> GetProperties(StructuralType type)
  1287. {
  1288. if (type.BuiltInTypeKind == BuiltInTypeKind.EntityType)
  1289. {
  1290. return ((EntityType)type).Properties;
  1291. }
  1292. else
  1293. {
  1294. return ((ComplexType)type).Properties;
  1295. }
  1296. }
  1297.  
  1298. protected void VerifyGetterAndSetterAccessibilityCompatability(EdmMember member)
  1299. {
  1300. string rawGetterAccessibility = Accessibility.ForReadOnlyProperty(member);
  1301. string rawSetterAccessibility = Accessibility.ForWriteOnlyProperty(member);
  1302.  
  1303. if ((rawGetterAccessibility == "internal" && rawSetterAccessibility == "protected") ||
  1304. (rawGetterAccessibility == "protected" && rawSetterAccessibility == "internal"))
  1305.  
  1306. {
  1307. Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6033", String.Format(CultureInfo.CurrentCulture,
  1308. GetResourceString("GeneratedPropertyAccessibilityConflict"),
  1309. member.Name, rawGetterAccessibility, rawSetterAccessibility)));
  1310. }
  1311. }
  1312.  
  1313. private void VerifyEntityTypeAndSetAccessibilityCompatability(EntitySet set)
  1314. {
  1315. string typeAccess = Accessibility.ForType(set.ElementType);
  1316. string setAccess = Accessibility.ForReadOnlyProperty(set);
  1317.  
  1318. if(typeAccess == "internal" && (setAccess == "public" || setAccess == "protected"))
  1319. {
  1320. Errors.Add(new System.CodeDom.Compiler.CompilerError(SourceCsdlPath, -1, -1, "6036", String.Format(CultureInfo.CurrentCulture,
  1321. GetResourceString("EntityTypeAndSetAccessibilityConflict"),
  1322. set.ElementType.Name, typeAccess, set.Name, setAccess)));
  1323. }
  1324. }
  1325.  
  1326. ////////
  1327. //////// UniqueIdentifierService
  1328. ////////
  1329. sealed class UniqueIdentifierService
  1330. {
  1331. private readonly HashSet<string> _knownIdentifiers;
  1332.  
  1333. public UniqueIdentifierService()
  1334. {
  1335. _knownIdentifiers = new HashSet<string>(StringComparer.Ordinal);
  1336. }
  1337.  
  1338. /// <summary>
  1339. /// Makes the supplied identifier unique within the scope by adding
  1340. /// a suffix (1, 2, 3, ...), and returns the unique identifier.
  1341. /// </summary>
  1342. public string AdjustIdentifier(string identifier)
  1343. {
  1344. // find a unique name by adding suffix as necessary
  1345. var numberOfConflicts = 0;
  1346. var adjustedIdentifier = identifier;
  1347.  
  1348. while (!_knownIdentifiers.Add(adjustedIdentifier))
  1349. {
  1350. ++numberOfConflicts;
  1351. adjustedIdentifier = identifier + numberOfConflicts.ToString(CultureInfo.InvariantCulture);
  1352. }
  1353.  
  1354. return adjustedIdentifier;
  1355. }
  1356. }
  1357.  
  1358. #>
  1359.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty