0

How do I make my constructor protected in when using entity framework database first?

When I generate an Entity Data Model from my database, the auto generated class contains a public constructor,

//------------------------------------------------------------------------------
// <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>
//------------------------------------------------------------------------------

namespace Domain.Models
{
    using System;
    using System.Collections.Generic;

    public partial class MyClass
    {
        public MyClass()
        {

what I would like is a protected constructor

    public partial class MyClass
    {
        protected MyClass()
        {
8
  • My initial reaction is that I don't think it's possible in database-first, due to the fact that any refreshing of the model will cause your manual changes to be overwritten. Commented Nov 13, 2014 at 14:29
  • Why would you want to do that? This way it would be impossible to create an instance of this class. Are you trying to prevent users from instantiating a base class? Then check whether you can mark the base class as abstract in the designer Commented Nov 13, 2014 at 14:30
  • @PanagiotisKanavos I am creating a partial class that requires a specific signature so that I can insure my models state is valid eg MyClass(person person) {this.Person = person}. Have a look here for a further explanation udidahan.com/2009/06/29/dont-create-aggregate-roots Commented Nov 13, 2014 at 14:33
  • If you were doing this with Code-First development instead, you could do something like this: thedatafarm.com/data-access/… Commented Nov 13, 2014 at 15:04
  • @IronMan84 This could (and should) be done by modifying the t4 template. Then these changes will not be overwritten by an update. Commented Nov 13, 2014 at 15:29

2 Answers 2

3

You can do this by modifying the t4 template that creates the model classes. Look for this part near the top of the file:

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

    if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
    {
#>
    public <#=code.Escape(entity)#>()
    {
<#

and replace the bottom line public <#=code.Escape(entity)#>() by

protected <#=code.Escape(entity)#>()

This change will create protected constructors for entity type. Lower in the file there is a similar construct for complex types, you may want to modify that one as well.

A word about "updates". If you update the model from the database, these changes will not be overwritten. However, if you update EF, a problem with modified t4 templates is that you have to do it again when you want to use the templates of the new version.

Sign up to request clarification or add additional context in comments.

Comments

1

You cant have a protected Model constructor is incorrect. Can under circumstances - See Link provided by Gert. http://msdn.microsoft.com/en-us/library/vstudio/dd468057%28v=vs.100%29.aspx Thanks Gert for correction.

So you could via T4 change.

Do you still see that as best way to solve your problem ?

You can use something like the validation interface IValidatableObject which EF will call during save operations to verify the data is ok.

Remember when reading data, EF fills poco instances and sticks reference in a context. When you fill the POCO instance you can trigger validations when you like, ef will call validate before saving. Search google for this topic.

eg

    /// <summary>
    /// Get called everytime  a Validation is triggered on an object. EG MVC model check or  EF save.
    /// </summary>
    public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {

        // Sample Implementation. 
        var validationResult = new List<ValidationResult>();

        // a field cant be null or empty when condition X is true.
        if ( SOME CONDTION that is true   ) {
          validationResult.Add(new ValidationResult(some field is required when...", new List<string>() {"FieldName"}));
          }

        return validationResult;
    }

3 Comments

Phil, EF can handle protected constructors (and members even private), it's even recommended for certain scenarios: msdn.microsoft.com/en-us/library/vstudio/….
Clearly this docu clarification is better info. Thanks Gert.
@philsoady I am already using validations the issue is not just one of validation and model state, the business domain is a fairly complex one so to prevent ambiguity I am creating an intention revelling API. Eg an assessment is always done against an Instituion so new assessment() breaks the business rules. new assessment(Institution) is valid. for a deeper explanation lostechies.com/jimmybogard/2010/02/24/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.