4

I have this annoying problem were every time I want to refresh my Entity Framework schema (Database First), I lose all validation code I had written (with Resource for translation, etc...) and then I need to get back to my previous code from version control and overwrite it the way it was prior to refreshing schema. I did find a patch to overpass this problem but I find it's quite some overhead.... I need some suggestions on how to probably handle that..please!!! So let say my model with validation and resources (shorter for the question) is the following:

public partial class tblReport
{
    public int id { get; set; }

    [Display(ResourceType = typeof(Resources.Admin), Name = "ReportName")]
    [Required(ErrorMessageResourceType = typeof(Resources.Admin), ErrorMessageResourceName = "Required")]
    public string reportName { get; set; }

    [Display(ResourceType = typeof(Resources.Admin), Name = "CreatedDate")]
    [Required(ErrorMessageResourceType = typeof(Resources.Admin), ErrorMessageResourceName = "Required")]
    public DateTime dtCreated { get; set; }
}

After doing a refresh of the EF Schema, it will erase everything and put it back to default as the following:

public partial class tblReport
{
    public int id { get; set; }

    public string reportName { get; set; }

    public DateTime dtCreated { get; set; }
}

Now I did find a patch as I said, which is to extend the tblReport class and put all validations in there, but this equals to a copy of 1 to 1 from EF Schema and inserting validations... So I do an Extend as the following:

public class tblReportModel : tblReport
{
    public int id { get; set; }

    [Display(ResourceType = typeof(Resources.Admin), Name = "ReportName")]
    [Required(ErrorMessageResourceType = typeof(Resources.Admin), ErrorMessageResourceName = "Required")]
    public string reportName { get; set; }

    [Display(ResourceType = typeof(Resources.Admin), Name = "CreatedDate")]
    [Required(ErrorMessageResourceType = typeof(Resources.Admin), ErrorMessageResourceName = "Required")]
    public DateTime dtCreated { get; set; }

    public tblReport ToTblReport()
    {
        tblReport tReport = new tblReport();

        tReport.dtCreated = this.dtCreated;
        tReport.reportName = this.reportName;
        tReport.id = this.id;

        return tReport;
    }

    public static tblReportModel ToTblReportModel(tblReport createdReport)
    {
        tblReportModel mReport = new tblReportModel();

        mReport.dtCreated = createdReport.dtCreated;
        mReport.reportName = createdReport.reportName;
        mReport.id = createdReport.id;

        return mReport;
    }
}

I find it's so much work for nothing and not only that, I need to update all my code in my Controller and go against the new tblReportModel for the Create/Edit pages so that they get the validations done. I does work this way but it's so much overhead...oh and doing it this way, I also get a bunch of warnings saying

'IntranetApplication.Models.tblReportModel.dtCreated' hides inherited member 'IntranetApplication.Models.tblReport.dtCreated'. Use the new keyword if hiding was intended.

Please!!! Does anyone have a better solution than this???

ghiscoding
  • 12,308
  • 6
  • 69
  • 112
  • Are you using Data-Base first? If yes, you must use MetaData extending your model. – Fals May 15 '14 at 21:00
  • Yes it's in the title of my question... Database First.. I don't know MetaData as I'm still on the learning curve of ASP MVC, can you give an answer? – ghiscoding May 15 '14 at 21:07
  • possible duplicate of [Data Annotations with Entity Framework 5.0 (database first)](http://stackoverflow.com/questions/15621656/data-annotations-with-entity-framework-5-0-database-first) – Fals May 15 '14 at 21:10
  • indeed it does look like an answer but since I'm still on the learning curve, I find it's missing some info in there... how am I suppose to call my code in the Controller after? Does the code change only happen inside this new Partial Class? I did the Partial Class as mentioned but I don't know what to do next. – ghiscoding May 15 '14 at 21:42
  • Which version of Entity Framework are you using? Do you have an .edmx file? – Erik Funkenbusch May 15 '14 at 23:31
  • @Erik EF6 I believe and yes I do have .edmx file – ghiscoding May 16 '14 at 03:30

1 Answers1

0

Using MetadataType or extending the auto-generated classes are both painful methods - read the question posted by Fals and you'll see what I mean.

What I do is that I have all my Data Access Layer code in a separate project. I then create another project with my Business Objects (I add the validation to these) and use AutoMapper to map objects between between the DAL and the Business Objects.

This approach provides better separation of concerns and makes it easy to switch to another ORM in the feature should you need/want to. It would be a matter of remapping the objects in AutoMapper.

Icarus
  • 63,293
  • 14
  • 100
  • 115
  • Thanks, I did read Fals link of the other answer but I find it's not complete as I'm still learning ASP MVC... and on your side, would you be able to provide example? Even if it's with your code for example, that would help..thanks for your time. – ghiscoding May 16 '14 at 03:32
  • @ghiscoding - I don't understand what's incomplete about it, or what's confusing. You just create a second partial class named just like the auto generated one, add the MetadataType attribute to it, then create a Metadata class that contains the same properties with your attributes. Yes, it's a lot of extra work, and that's one reason you shouldn't pass your data models directly to your views, because your data models have different requirements than your views. – Erik Funkenbusch May 16 '14 at 04:01
  • @ErikFunkenbusch since I come from a PHP world, I didn't even know what is Partial Class, I never use that. From that being said, it's not clear to me what and how I would use it in the Controller, do I use it as `tblReport` or `tblReportPartial` that was not mentioned in the answer. For me ASP MVC is a lot different especially the OOP compare to PHP OOP, so that is what get me confuse... – ghiscoding May 16 '14 at 13:22
  • 1
    @ghiscoding partial classes allow you to split a class into two separate definitions. At compile time, the definitions are merged into a single class. They must be named the same, so no.. it wouldn't have the name partial in it. The point here is that you allow the generator to regenerate one part, but your other part with the metadata does not get regenerated. At compile time, the two definitions are merged into a single class. See http://hartzer.wordpress.com/2010/01/26/mvc-buddy-class/ – Erik Funkenbusch May 16 '14 at 15:08
  • @Icarus I would still like to see code sample if possible so I could +1 on it, I'm more of a visual person :) – ghiscoding May 16 '14 at 18:45
  • 1
    @ghiscoding I will post some sample code tonight when I get home. Hang in there... ;) Just remember that what I propose will not make you write less code; it's just a technique that I think is good since provides better separation of concerns and project organization over all. – Icarus May 16 '14 at 19:20