locked
How do I override the primitive properties and methods when using DbContext? RRS feed

  • Question

  • Hi all,

    Using Database First with DbContext Generator here.
    We are facing a problem where all the code we add in our classes are overwritten by the T4 templates.
    For the Data Annotations we are creating buddy classes in a different partial class file which solves one the issues.
    However, we are trying to find out how to override some methods such as when a primitive property is created, and also prevent that 
    from being overwritten by the T4 templates, for instance:

        public partial class User
        {
            public User()
            {
                ...//some code here
            }
       
            public System.Guid UserID { get; set; }          //<= we want to modify this and also be able to override the OnCreate() method
            public System.DateTime Created { get; set; }
            ...

    We would like to add something like:


    public System.Guid UserID
    {
      get
      {
        if (userID == Guid.Empty)
        {
     userID = Guid.NewGuid();
        }
     return userID;
      }

      set
      {
     userID = value;
      }
    }


    It looks like ObjectContext has some methods (see sample code below) that allow me to do that but I am using DbContext instead.

            public global::System.Int32 DinnerID
            {
                get
                {
                    return _DinnerID;
                }
                set
                {
                    if (_DinnerID != value)
                    {
                        OnDinnerIDChanging(value);
                        ReportPropertyChanging("DinnerID");
                        _DinnerID = StructuralObject.SetValidValue(value);
                        ReportPropertyChanged("DinnerID");
                        OnDinnerIDChanged();
                    }
                }
            }

    Thank you


    Max
    Wednesday, November 16, 2011 9:23 PM

Answers

  • Hi,

    What you need to do is to modify the <YourModel>.tt file.

    Line 226 to 250 in this file you have the code that actually writes your properties.

    What you could do is to replace the existing code with this

    void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
    {
        WriteCustomProperty(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());
        WritePlainProperty(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 WritePlainProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
    {
    #>
        <#=accessibility#> <#=type#> <#=name#> { <#=getterAccessibility#>get; <#=setterAccessibility#>set; }
    <#+
    }
    
    void WriteCustomProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
    {
    #>
    
        <#=accessibility#> <#=type#> <#=name#> 
    	{ 
    		<#=getterAccessibility#>get
    		{
    			return _<#=name#>;
    		}
    		<#=setterAccessibility#>set
    		{
    			if(_<#=name#> != value)
    			{
    				On<#=name#>Changing(value);
    				_<#=name#> = value;
    				On<#=name#>Changed();
    			}
    		}
    	}
    	private <#=type#> _<#=name#>;
    
    	private partial void On<#=name#>Changing(<#=type#> newValue);
    	private partial void On<#=name#>Changed();
    <#+
    }
    

    And you will get properties that are similar to the default.

    A remark: This is untested code, so minor adjustment may be neccessary

    Remember that .tt files are templates that you can modify to suit your needs for code, the one provided are good as base but often you would have to modify them to suit your needs.

    Hope this helps!


    --Rune

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by Maximusdm Thursday, November 17, 2011 5:54 PM
    Thursday, November 17, 2011 7:18 AM

All replies

  • Hi,

    What you need to do is to modify the <YourModel>.tt file.

    Line 226 to 250 in this file you have the code that actually writes your properties.

    What you could do is to replace the existing code with this

    void WriteProperty(CodeGenerationTools code, EdmProperty edmProperty)
    {
        WriteCustomProperty(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());
        WritePlainProperty(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 WritePlainProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
    {
    #>
        <#=accessibility#> <#=type#> <#=name#> { <#=getterAccessibility#>get; <#=setterAccessibility#>set; }
    <#+
    }
    
    void WriteCustomProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
    {
    #>
    
        <#=accessibility#> <#=type#> <#=name#> 
    	{ 
    		<#=getterAccessibility#>get
    		{
    			return _<#=name#>;
    		}
    		<#=setterAccessibility#>set
    		{
    			if(_<#=name#> != value)
    			{
    				On<#=name#>Changing(value);
    				_<#=name#> = value;
    				On<#=name#>Changed();
    			}
    		}
    	}
    	private <#=type#> _<#=name#>;
    
    	private partial void On<#=name#>Changing(<#=type#> newValue);
    	private partial void On<#=name#>Changed();
    <#+
    }
    

    And you will get properties that are similar to the default.

    A remark: This is untested code, so minor adjustment may be neccessary

    Remember that .tt files are templates that you can modify to suit your needs for code, the one provided are good as base but often you would have to modify them to suit your needs.

    Hope this helps!


    --Rune

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by Maximusdm Thursday, November 17, 2011 5:54 PM
    Thursday, November 17, 2011 7:18 AM
  • wow... I definitely would not like to mess with those templates. EF is supposed to make our lives easier(grin)

    I am now thinking about going back to use ObjectContext then. Or perhaps just the DbContext Fluent API generator to create all my classes and then modify them  without being worried about the .tt templates.

    EF has been a long curve...you think you are learning then you realize that this is just the tip of the iceberg....sighs....

     

    thanks


    Max
    Thursday, November 17, 2011 3:46 PM