简体   繁体   中英

Calling Entity Framework code classes from other Entity Framework Controller classes

I have a lot of repetitive code in my controllers which I am trying to offload to a shared helper class so that I can update in one place instead of the hundreds where they currently are.

I have extracted the repetitive code to a separate method, but, I couldn't work out how to actually get the data from the database without calling entity framework again.

To give a very rough example, before:

class foo{
private MyDbContext db = new MyDbContext();
Public Actionresult test()
{
     ViewModel.bla = db.bla.tolist();
     ... about 6 more lines that are the same on many methods...
     ViewModel.page = db.uniquelogic.tolist();
}

after:

class foo{
private MyDbContext db = new MyDbContext();
Public Actionresult test()
{
     ViewModel.bla = new dbhelper.getbla();
     ViewModel.page = db.uniquelogic.tolist();
}

shared file (bla.cs):

class dbhelper{
private MyDbContext db = new MyDbCotnext();
public bla getbla()
{
...logic here
return bla
}

So, both methods work here and I prefer using the second as I only have to update it once, but, my question is:

  1. Is there anything wrong with calling the DbContext multiple times? I remember with EF 3 (the last time I used this), it caused errors and I was surprised it worked now.
  2. In controllers, there is a seprate dispose clause, there is nothing in a standard class that I can call. Is this a problem?
  3. Is there a better way to do this? It doesn't "feel" correct, but, I'm unsure what else to do.

Logic common to multiple Controller classes could be moved to a base " BaseController " class, thus also giving you automatic control over the lifetime of the object too:

public abstract class BaseController : Controller {

    private MyDbContext _db;

    protected MyDbContext DBContext {
        get { return _db ?? ( _db = new MyDbContext() ); }
    }

    protected void PopulateViewModel(ViewModel vm) {
        vm.Bla = this.DBContext.GetBla();
        vm.Page = this.DBContext.UniqueLogic.ToList();
    }

    protected override void Dispose(bool disposing) {
        if (disposing && this._db != null) {
            this._db.Dispose();
            this._db = null;
        }
        base.Dispose(disposing);
    }
}

Then in your derived controllers:

public class SomeAreaController : BaseController {

    public ActionResult Test() {

        ViewModel vm = new ViewModel();
        this.PopulateViewModel( vm );

        // and if you still need access to a DbContext, use the inherited property:
        this.DBContext.DoSomething();

        return this.View( vm );
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM