<# /* * Sam Meacham (www.samscode.com) * Template to auto generate DTO classes based on your entity data model (edmx). */ // // CONFIG SECTION. Change these values to be specific to your project. // // This should be the relative path from this template to your .edmx file string inputFile = "../PersonEntities.edmx"; #> <#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ output extension=".cs"#> <# CodeGenerationTools code = new CodeGenerationTools(this); MetadataLoader loader = new MetadataLoader(this); MetadataTools ef = new MetadataTools(this); EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile); string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); // Write out support code to primary template output file WriteHeader(fileManager); BeginNamespace(namespaceName, code); #> public static class DtoExtensionMethods { <# foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) { #> /// /// Easily create DTO objects from actual domain entity objects /// public static <#=code.Escape(entity)#>[] ToEntities(this IEnumerable<<#=code.Escape(entity)#>Dto> dtos) { return AutoMapper.Mapper.MapDto>, <#=code.Escape(entity)#>[]>(dtos); } <# } #> } <# EndNamespace(namespaceName); // ******************************************************************************** // *** Emit Entity Types ********************************************************** // ******************************************************************************** foreach (EntityType entity in ItemCollection.GetItems().OrderBy(e => e.Name)) { fileManager.StartNewFile(entity.Name + "Dto.cs"); BeginNamespace(namespaceName, code); bool entityHasNullableFKs = entity.NavigationProperties.Any(np => np.GetDependentProperties().Any(p=>ef.IsNullable(p))); #> using System.Runtime.Serialization; /// /// TODO: Decide if I want to use FixupCollection{T} classes, with ICollection{T}, or if I just want these to be as plain as possible (manual fixup, etc). /// Also, do I want the FK fixup too? Could be nice... /// [DataContract] <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#> class <#=code.Escape(entity)#>Dto<#=code.StringBefore(" : ", code.Escape(entity.BaseType))#> { /// Parameterless constructor (important for serialization) public <#=code.Escape(entity)#>Dto() {} public string ToJson(bool format = false) { return JsonHelper.Serialize(this, format); } public <#=code.Escape(entity)#> ToEntity() { return AutoMapper.Mapper.Map<<#=code.Escape(entity)#>Dto, <#=code.Escape(entity)#>>(this); } // ******************************************************************************** // *** Primitive properties ******************************************************* // ******************************************************************************** <# foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity)) { bool isDefaultValueDefinedInModel = (edmProperty.DefaultValue != null); bool generateAutomaticProperty = false; #> [DataMember] <#= Accessibility.ForProperty(edmProperty) #> <#=code.Escape(edmProperty.TypeUsage)#> <#=code.Escape(edmProperty)#><# if (isDefaultValueDefinedInModel) { #> <#=code.SpaceAfter(Accessibility.ForGetter(edmProperty))#>get { return <#=code.FieldName(edmProperty)#>; } <#=code.SpaceAfter(Accessibility.ForSetter(edmProperty))#>set { <#=code.FieldName(edmProperty)#> = value; } <# } else { generateAutomaticProperty = true; #> { get; set; } <# } if (!generateAutomaticProperty) { #> private <#=code.Escape(edmProperty.TypeUsage)#> <#=code.FieldName(edmProperty)#><#=code.StringBefore(" = ", code.CreateLiteral(edmProperty.DefaultValue))#>; <# } } #> // ******************************************************************************** // *** Complex properties ********************************************************* // ******************************************************************************** <# foreach(EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity)) { #> [DataMember] <#= Accessibility.ForProperty(edmProperty)#> <#=code.Escape(edmProperty.TypeUsage)#>Dto <#=code.Escape(edmProperty)#> { <#=code.SpaceAfter(Accessibility.ForGetter(edmProperty))#>get { return <#=code.FieldName(edmProperty)#>; } <#=code.SpaceAfter(Accessibility.ForSetter(edmProperty))#>set { <#=code.FieldName(edmProperty)#> = value; } } private <#=code.Escape(edmProperty.TypeUsage)#>Dto <#=code.FieldName(edmProperty)#> = new <#=code.Escape(edmProperty.TypeUsage)#>Dto(); <# } #> // ******************************************************************************** // *** Navigation properties ****************************************************** // ******************************************************************************** <# foreach (NavigationProperty navProperty in entity.NavigationProperties.Where(np => np.DeclaringType == entity)) { if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) { #> [DataMember] <#= Accessibility.ForReadOnlyProperty(navProperty) #> List<<#=code.Escape(navProperty.ToEndMember.GetEntityType())#>Dto> <#=code.Escape(navProperty)#> { get; set; } <# } else { #> [DataMember] <#= Accessibility.ForProperty(navProperty)#> <#=code.Escape(navProperty.ToEndMember.GetEntityType())#>Dto <#=code.Escape(navProperty)#> { get; set; } <# } #> <# } #> } // end class <# EndNamespace(namespaceName); } // end of the outermost foreach going through each entity type // ******************************************************************************** // *** Create the complex type classes ******************************************** // ******************************************************************************** foreach (ComplexType complex in ItemCollection.GetItems().OrderBy(e => e.Name)) { fileManager.StartNewFile(complex.Name + ".cs"); BeginNamespace(namespaceName, code); #> <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> { <# foreach(EdmProperty edmProperty in complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex)) { bool isDefaultValueDefinedInModel = (edmProperty.DefaultValue != null); #> <#=Accessibility.ForProperty(edmProperty)#> <#=code.Escape(edmProperty.TypeUsage)#> <#=code.Escape(edmProperty)#> <# if (isDefaultValueDefinedInModel) { #> { <#=code.SpaceAfter(Accessibility.ForGetter(edmProperty))#>get { return <#=code.FieldName(edmProperty)#>; } <#=code.SpaceAfter(Accessibility.ForSetter(edmProperty))#>set { <#=code.FieldName(edmProperty)#> = value; } } private <#=code.Escape(edmProperty.TypeUsage)#> <#=code.FieldName(edmProperty)#><#=code.StringBefore(" = ", code.CreateLiteral(edmProperty.DefaultValue))#>; <# } else { #> { <#=code.SpaceAfter(Accessibility.ForGetter(edmProperty))#>get; <#=code.SpaceAfter(Accessibility.ForSetter(edmProperty))#>set; } <# } } foreach(EdmProperty edmProperty in complex.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == complex)) { #> <#=Accessibility.ForProperty(edmProperty)#> <#=code.Escape(edmProperty.TypeUsage)#> <#=code.Escape(edmProperty)#> { <#=code.SpaceAfter(Accessibility.ForGetter(edmProperty))#>get { return <#=code.FieldName(edmProperty)#>; } <#=code.SpaceAfter(Accessibility.ForSetter(edmProperty))#>set { <#=code.FieldName(edmProperty)#> = value; } } private <#=code.Escape(edmProperty.TypeUsage)#> <#=code.FieldName(edmProperty)#> = new <#=code.Escape(edmProperty.TypeUsage)#>(); <# } #> } <# EndNamespace(namespaceName); } fileManager.Process(); #> <#+ void WriteHeader(EntityFrameworkTemplateFileManager fileManager, params string[] extraUsings) { fileManager.StartHeader(); #> //------------------------------------------------------------------------------ // // This code was generated from a template. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ using System; using System.Collections.Generic; <#=String.Join(String.Empty, extraUsings.Select(u => "using " + u + ";" + Environment.NewLine).ToArray())#> <#+ fileManager.EndBlock(); } void BeginNamespace(string namespaceName, CodeGenerationTools code) { CodeRegion region = new CodeRegion(this); if (!String.IsNullOrEmpty(namespaceName)) { #> namespace <#=code.EscapeNamespace(namespaceName)#> { <#+ PushIndent(CodeRegion.GetIndent(1)); } } void EndNamespace(string namespaceName) { if (!String.IsNullOrEmpty(namespaceName)) { PopIndent(); #> } <#+ } } #>