3

I just joined a new company and my manager just joined too, and he wants to change the way we program. basically do what he does. I'm wondering what's the difference, pros, cons, limitation and problems if there'll be any..here's the sample

namespace Models //this is the model part of from edmx
{
using System;
using System.Collections.Generic;


public partial class MyModelClass
{
    public int ID { get; set; }
    public Nullable<System.DateTime> PostDate { get; set; }
    public string MyContent { get; set; }
}

}

this is the metadata:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    namespace Models
    {
         public class MyModelMetaData
         {
           //he wants all data annotation here
           public int ID { get; set; }
           public Nullable<System.DateTime> PostDate { get; set; }
           public string MyContent { get; set; }
         }
   }

this is the partial:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;

    namespace Models
   {
        [MetadataType(typeof(MyModelMetaData))]
        public partial class MyModelClass or MyModelClassPartial
        {

           //He wants the programming algorithm to go here
       }
  }

Please enlightened me. and he wants to create different metadata and partial classes per model class..way too many files involved.

thank you..i need an answer as to why..if you think his method is good..I will do this..but if you think this will cause problem in the future and more coding will be involve..i need to know

CyberNinja
  • 872
  • 9
  • 25
  • he doesn't explain..he just want us do it that way..coz that's how he learned it..he's new to mvc too. – CyberNinja Dec 15 '16 at 18:14
  • 1
    well think on this. If MyClass is auto-generated and you add data annotation attributes to it. what will happen if you change the model?. I think his recommendation is good in this case. – Juan M. Elosegui Dec 15 '16 at 18:18
  • BTW `public class MyModelPartial` should be `public partial class MyClass` with a different file name. – Juan M. Elosegui Dec 15 '16 at 18:21
  • Partial classes should be used only for designer generated code. It should not be used for organization or separation of concerns, as it just leads to unnecessary obfuscation. Wanting to split one class across two files to separate some aspect of the class's behavior indicates that the class is far too big and is in violation of the single responsibility principle. – Daniel Mann Dec 16 '16 at 14:07

2 Answers2

13

The first class you show, the entity classes, are generated from the database every time you save the EDMX (or when you execute the T4 Template).

This causes the file containing public partial class MyClass under the EDMX to be regenerated. So you cannot alter it, because the next time someone refreshes a table or adds one, your changes are gone.

That's why entity classes are generated as a partial: so you can create another partial to the same class to do your modifications in.

However, if you want to annotate your entity's properties with metadata, you cannot redefine the same property in the other partial class: the same name can only be used by one member of a type. So you can't do this:

// Entity class
public partial class FooEntity
{
    public string Name { get; set;} 
}

// User-created partial class
public partial class FooEntity
{
    [Required]
    public string Name { get; set;} 
}

Because that code expresses you want two properties named Name in the FooEntity class, which is not valid.

So you'll have to come up with another way to add metadata to the type. Enter the [MetadataType] attribute. This works by creating a new class with the same properties as the class to be annotated. Here, using reflection, the metadata is resolved based on member name.

So when you create a metadata class for the above annotation:

public class FooEntityMetadata
{
    [Required]
    public string Name { get; set;} 
}

You can apply it to the user-created partial:

// User-created partial class
[MetadataType(typeof(FooEntityMetadata))]
public partial class FooEntity
{
}

And also, in the latter partial, you can add members that add functionality to the entity model. New ([NotMapped]) properties and new methods for example.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • thanks for this..so the partial class name should differ from the entity model class name? coz he made change my partial class name to that same of the entity's. plus the name space should match the models'? how is this whole set up mapped to the model? – CyberNinja Dec 16 '16 at 13:59
  • When you split up a class in multiple partial definitions, the full name including the namespace must match, otherwise you end up with two unrelated classes. The Metadata class must have a different name. I don't know what you mean by "how is this mapped to the model". – CodeCaster Dec 16 '16 at 14:04
0

I think the one use could be to not pollute the main class.

For example if you have a lot of attribute for validation (using dataannotation) and you don't want to have them in the main class you could use the MetadataTypeAttribute for that.

Another use could be if your class is auto-generated and you need to add some decoration (more attributes) to your properties without changing the autogenerated code.

Juan M. Elosegui
  • 6,471
  • 5
  • 35
  • 48