superservo15
superservo15

Reputation: 51

MVC Scaffolding with Repository Pattern - Saving children objects as a transaction

I have been scouring forums and repository pattern blogs for some clear direction on how I should be coding my project and I'm stuck. Any help or guidance from you guys would be much approciated :)

I started my project as EF5 MVC4 Razor Code First and decided to use MVCScaffolding to generate all my controllers, views and repositories. This was my first project with these technologies, I was just told that this was how the team was doing it now (but the previous developers did model first and hand coded their contexts).

SO, all is great, we're coding a bunch of screens, but one of our screens is a complex one that involves many models/sub modlels (ie/ Object model has FKs to Responses, Attachments, Reviewers, etc...). The user adds a bunch of data, selects one or more reviewers, adds 0 or more attachments. Then they hit Save!

Now my big problem is that I want to save all this data as one transaction, and if something fails on one of the children models (ie/ attachments) the transaction will roll back. However, the way the MVCScaffolding repositories are created, each model has it's own instance of DB Context and it's own Save. And the controllers accept each unique repository as parameters for loading the screen data. Another thing to note is for this screen we are using a ViewModel to load the data, and then wrote custom mappers to map back to the different models for saving. We can save each piece separately, and possibly the solution is just to wrap TransactionScope around my save, but I also want to reduce the number of calls to the db, as each repository save does a call.

I thought I could add code to the parent repository for a UnitsOfWork type save that would add/edit all the child obejcts in one context object, but that seems like a hack more than anything, and I want to code this properly.

One of the other projects here just made a custom DB context and all Save methods were in that class, is that the best way to do it? Another dev did code first but hand coded all his Save methods. None of them are in a standard place and he is using TransactionScope with a DBContext inside (is that overkill or does DBContext not handle transactions)?

Since I'm so new to this, I need help and no one I work with seems to agree on a proper method. I'm not sure if my model is wrong for an "MVC App" since I'm such a database heavy thinker.

Below is a sample of my models, any guidance is appreciated. Thanks :)

public class Anomaly 
{
    [Key]
    public int AnomalyId { get; set; }

    public string Subject { get; set; }

    public int PlantId { get; set; }
    [ForeignKey("PlantId")]
    public virtual Plant Plant { get; set; }

    public DateTime? ReviewByDate { get; set; }

    public virtual ICollection<AnomalyReviewer> AnomolyReviewers { get; set; }
    public virtual ICollection<AnomalyAttachment> AnomalyAttachments { get; set; }

}

    public class AnomalyAttachment 
{
    [Key]
    public int AnomalyAttachmentId { get; set; }

    public int AnomalyId { get; set; }
    [ForeignKey("AnomalyId")]
    public virtual Anomaly Anomaly { get; set; }

    public string FilePath { get; set; }
    public string FileName { get; set; }
    public string FileExtension { get; set; }
    public string Notes { get; set; }           

}

ps. that is just a sample... thanks!

Upvotes: 0

Views: 1280

Answers (1)

Anonymous
Anonymous

Reputation: 11

Just create a class 'Master' that inherits from Controller. Then write all your queries there as in public User GetUserById(Int32 id) Finally create a function that does a call to the private!! implementation of DbContext.

I would usually give that function a enum of SystemEvents so i've got a reference of whats happening if something would fail... of course you would need to write your own notificator or model to record your own errors into the database for personal testing...

ive done all this because I can write all my code and found out that Repository Pattern is overkill most of the time if you actually think about it.

Upvotes: 1

Related Questions