locked
T4 Code Generation DBContext - Add Serializable RRS feed

  • Question

  • Hi. With reference to my last question which was kindly answered. here

    I think I have found the place to add the Serializable tag in the T4 code.

    void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
    {
    	WriteProperty(Accessibility.ForProperty(edmProperty),
                      code.Escape(edmProperty.TypeUsage),
                      code.Escape(edmProperty),
                      code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                      code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
    }
    I would love to be able to add the 

    [Serializable()] to the auto generated code but have found no answers around.

    Eventually to look like this 

    [Serializable()]
        public partial class AdjustmentsLive
        {
            public AdjustmentsLive()
            {
                this.VolumeTrends = new HashSet<VolumeTrend>();
            }
    Thanks fro any help. Scott



    Thursday, December 20, 2012 6:18 PM

Answers

  • Try it like this:

    [Serializable()]
    <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#> {

    Also What version of EF are you using and Visual Studio.?


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by scottsanpedro Friday, December 21, 2012 3:15 PM
    Friday, December 21, 2012 3:13 PM

All replies

  • Hi Scott;

    I am no expert at modifying the Entity Framework T4 templet but I have tried the following and it works. Look for a section of code that looks like this near the top of the file and insert [Serializable()] where I did in the below code.

    foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
    {
        fileManager.StartNewFile(entity.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
    	[Serializable()]
    <#=codeStringGenerator.EntityClassOpening(entity)#>
    {
    <#
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
        var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
        var complexProperties = typeMapper.GetComplexProperties(entity);
    

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Friday, December 21, 2012 3:47 AM
  • Thanks once again Fernando. Very kind.

    I m using the DBContext T4 auto generated code and appears to be different. The line I believe to be the important part is as above. I'll keep looking into this and reply back once found out. Cheers Scott

    Friday, December 21, 2012 2:29 PM
  • Can you post the templet file here so I can have a look?

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Friday, December 21, 2012 2:43 PM
  • <#
    //*********************************************************
    //
    //    Copyright (c) Microsoft. All rights reserved.
    //    This code is licensed under the Microsoft Public License.
    //    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
    //    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
    //    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
    //    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
    //
    //*********************************************************
    #>
    <#@ 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);
    CodeRegion region = new CodeRegion(this, 1);
    MetadataTools ef = new MetadataTools(this);
     
    string inputFile = @"HiggidyPies.edmx";
    EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
    string namespaceName = code.VsNamespaceSuggestion();
     
    EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
    WriteHeader(fileManager);
     
    foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
    {
        fileManager.StartNewFile(entity.Name + ".cs");
        BeginNamespace(namespaceName, code);
    #>
    <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
    {
    <#
        var propertiesWithDefaultValues = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && p.DefaultValue != null);
        var collectionNavigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
        var complexProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity);
     
        if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
        {
    #>
        public <#=code.Escape(entity)#>()
        {
    <#
            foreach (var edmProperty in propertiesWithDefaultValues)
            {
    #>
            this.<#=code.Escape(edmProperty)#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
    <#
            }
     
            foreach (var navigationProperty in collectionNavigationProperties)
            {
    #>
            this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=code.Escape(navigationProperty.ToEndMember.GetEntityType())#>>();
    <#
            }
     
            foreach (var complexProperty in complexProperties)
            {
    #>
            this.<#=code.Escape(complexProperty)#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
    <#
            }
    #>
        }
     
    <#
        }
     
        var primitiveProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity);
        if (primitiveProperties.Any())
        {
            foreach (var edmProperty in primitiveProperties)
            {
                WriteProperty(code, edmProperty);
            }
        }
     
        if (complexProperties.Any())
        {
    #>
     
    <#
            foreach(var complexProperty in complexProperties)
            {
                WriteProperty(code, complexProperty);
            }
        }
     
        var navigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity);
        if (navigationProperties.Any())
        {
    #>
     
    <#
            foreach (var navigationProperty in navigationProperties)
            {
                WriteNavigationProperty(code, navigationProperty);
            }
        }
    #>
    }
     
    <#
        EndNamespace(namespaceName);
    }
     
    foreach (var complex in ItemCollection.GetItems<ComplexType>().OrderBy(e => e.Name))
    {
        fileManager.StartNewFile(complex.Name + ".cs");
        BeginNamespace(namespaceName, code);
    #>
    <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
    {
    <#
        var complexProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == complex);
        var propertiesWithDefaultValues = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex && p.DefaultValue != null);
     
        if (propertiesWithDefaultValues.Any() || complexProperties.Any())
        {
    #>
        public <#=code.Escape(complex)#>()
        {
    <#
            foreach (var edmProperty in propertiesWithDefaultValues)
            {
    #>
            this.<#=code.Escape(edmProperty)#> = <#=code.CreateLiteral(edmProperty.DefaultValue)#>;
    <#
            }
     
            foreach (var complexProperty in complexProperties)
            {
    #>
            this.<#=code.Escape(complexProperty)#> = new <#=code.Escape(complexProperty.TypeUsage)#>();
    <#
            }
    #>
        }
     
    <#
        }
     
        var primitiveProperties = complex.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == complex);
        if (primitiveProperties.Any())
        {
            foreach(var edmProperty in primitiveProperties)
            {
                WriteProperty(code, edmProperty);
            }
        }
     
        if (complexProperties.Any())
        {
    #>
     
    <#
            foreach(var edmProperty in complexProperties)
            {
                WriteProperty(code, edmProperty);
            }
        }
    #>
    }
     
    <#
        EndNamespace(namespaceName);
    }
     
    if (!VerifyTypesAreCaseInsensitiveUnique(ItemCollection))
    {
        return "";
    }
     
    fileManager.Process();
     
    #>
    <#+
    void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
    {
        fileManager.StartHeader();
    #>
    //------------------------------------------------------------------------------
    // <auto-generated>
    //    This code was generated from a template.
    //
    //    Manual changes to this file may cause unexpected behavior in your application.
    //    Manual changes to this file will be overwritten if the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
     
    using System;
    using System.Collections.Generic;
     
    <#+
        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();
    #>
    }
    <#+
        }
    }
     
    void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
    {
    	WriteProperty(Accessibility.ForProperty(edmProperty),
                      code.Escape(edmProperty.TypeUsage),
                      code.Escape(edmProperty),
                      code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                      code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
    }
     
    void WriteNavigationProperty(CodeGenerationTools code, NavigationProperty navigationProperty)
    {
        var endType = code.Escape(navigationProperty.ToEndMember.GetEntityType());
        WriteProperty(PropertyVirtualModifier(Accessibility.ForProperty(navigationProperty)),
                      navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
                      code.Escape(navigationProperty),
                      code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
                      code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
    }
     
    void WriteProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
    {
    #>
    	<#=accessibility#> <#=type#> <#=name#> { <#=getterAccessibility#>get; <#=setterAccessibility#>set; }
    <#+
    }
     
    string PropertyVirtualModifier(string accessibility)
    {
        return accessibility + (accessibility != "private" ? " virtual" : "");
    }
     
    bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
    {
        var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
        foreach(var type in itemCollection.GetItems<StructuralType>())
        {
            if (!(type is EntityType || type is ComplexType))
            {
                continue;
            }
     
            if (alreadySeen.ContainsKey(type.FullName))
            {
                Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
                return false;
            }
            else
            {
                alreadySeen.Add(type.FullName, true);
            }
        }
     
        return true;
    }
    #>
    
    Friday, December 21, 2012 2:46 PM
  • Try it like this:

    [Serializable()]
    <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#> {

    Also What version of EF are you using and Visual Studio.?


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by scottsanpedro Friday, December 21, 2012 3:15 PM
    Friday, December 21, 2012 3:13 PM
  • perfect. I assumed it was further down the code.

    I am using EF 4.2.0.0 and Visual studio 2012.

    Many thanks for your help. Scott :)

    Friday, December 21, 2012 3:16 PM
  •   

    Not a problem. Have a great day.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Friday, December 21, 2012 3:17 PM