我可以传递一个'using'上下文到c#中的另一个方法吗? [英] Can I pass a 'using' context to another method in c#?

查看:94
本文介绍了我可以传递一个'using'上下文到c#中的另一个方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些EF代码来检索控制器中的一些对象,但我想分裂我的函数,以提高代码重用。

I have some EF code to retrieve some objects in a controller, but I want to split off my functions to improve code reuse.

我的代码目前看起来像这样:

My code currently looks something like this:

public ActionResult SentMessages(){
    MyModel model = new MyModel();
    int user_id = GetCurrentUserId();
    using(DataContext db = new DataContext()){
        model.Messages = 
               db.Messages
               .Where(x => x.sent == true)
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_sent)
               .Take(10)
               .ToList();
        model.Groups = db.Groups
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_created)
               .ToList();
    }
    return model;
}



我想将它拆分为可重用的代码块, )like this

I want to split it into reusable code chunks, (and make my controllers smaller) like so

public ActionResult SentMessages(){
    MyModel model = new MyModel();
    int user_id = GetCurrentUserId();
    model.Messages = GetLastTenMessages(user_id);
    model.Groups = GetGroups(user_id);
    return model;
}

public static List<Message> GetLastTenMessages(int user_id){
    using(DataContext db = new DataContext()){
        return db.Messages
               .Where(x => x.sent == true)
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_sent)
               .Take(10)
               .ToList();
    }
}

public static List<Group> GetGroups(int user_id){        
    using(DataContext db = new DataContext()){
        return db.Groups
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_created)
               .ToList();
    }
}

但是,这会导致两个独立的数据库连接(据我所理解)。每个查询都打开和关闭一个。

However, this results in two separate connections to the database (as far as I understand). One is opened and closed for each query.

是否有任何方法可以将上下文传递给方法,例如

Is there any way to pass the context to the method, something like this

public ActionResult SentMessages(){
    MyModel model = new MyModel();
    int user_id = GetCurrentUserId();
    using(DataContext db = new DataContext()){
        model.Messages = GetLastTenMessages(user_id, db);
        model.Groups = GetGroups(user_id, db);
    }
    return model;
}

public static List<Message> GetLastTenMessages(int user_id, DataContext db){
        return db.Messages
               .Where(x => x.sent == true)
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_sent)
               .Take(10)
               .ToList();
}

public static List<Group> GetGroups(int user_id, DataContext db){        
        return db.Groups
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_created)
               .ToList();
}

有这样我可以做,代码还可以使用最小数量的数据库连接?

Is there something like this I can do so that I can both separate out my code and also use the minimum number of database connections possible?

推荐答案

我会先朝着服务类的方向移动。所以你可以有这样一个新类:

I would move in the direction of a Service class first. So you could have a new class like this:

public class UserService
{

private DataContext _db;
//private int _user_id

public UserService(DataContext db)
{
   _db = db
   //perhaps it would be better to get the user id here
   //rather than pass it in to the methods as a parameter
   //_user_id = GetCurrentUserId();
   //or maybe put HttpContext into DataContext and do this:
   //_user_id = db.GetCurrentUserId();
}

private List<Message> GetLastTenMessages(int user_id){
        return _db.Messages
               .Where(x => x.sent == true)
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_sent)
               .Take(10)
               .ToList();
}

private List<Group> GetGroups(int user_id){        
        return _db.Groups
               .Where(x => x.user_id == user_id)
               .Where(x => x.date_deleted == null)
               .OrderBy(x => x.date_created)
               .ToList();
}

public MyModel GetSentMessages(int user_id)
{
        MyModel model = new MyModel();
        model.Messages = GetLastTenMessages(user_id, db);
        model.Groups = GetGroups(user_id, db);
        return model
    }
}
}

然后你的控制器看起来像这样

Then your controller will look like this

public ActionResult SentMessages(){
    using(DataContext db = new DataContext()){
        var us = new UserService(db);
        return View(us.GetSentMessages(GetCurrentUserId()));
    }
}

然后我将介绍数据库访问。
UserService 会迁移到这样的:

Then I'd look to introduce repositories for the data access. The UserService would then migrate to something like this:

public class UserService
{
    public UserService(DataContext db)
    {
       _db = db;
       _msgRepo = new MessageRepository(_db.Messages);
       _groupsRepo = new GroupsRepository(_db.Groups);
    }

    public MyModel GetSentMessages()
    {
            MyModel model = new MyModel();
            model.Messages = _msgRepo.GetLastTenMessages(db.user_id);
            model.Groups = _groupsRepo.GetGroups(db.user_id);
            return model
        }
    }
}

然后我会考虑将 DbContext 包含在我自己的 UnitOfWork 类中。
UserService 会迁移到这样的:

Then I'd think about wrapping the DbContext in my own UnitOfWork class. The UserService would then migrate to something like this:

public class UserService
{
    private UnitOfWork _uow;

    public UserService(UnitOfWork uow)
    {
        _uow = uow;
    }

    public MyModel GetSentMessages()
    {
            MyModel model = new MyModel();
            model.Messages = _uow.MessageRepo.GetLastTenMessages();
            model.Groups = _uow.GroupRepo.GetGroups();
            return model
        }
    }

到这:

private UnitOfWork _uow;

public UserController(UnitOfWork uow)
{
    _uow = uow;
    _us = new UserService(_uow);
}

public ActionResult SentMessages()
{
   return View(us.GetSentMessages());     
}

protected override void Dispose(bool disposing)
{
    if (disposing)
        _uow.Dispose();
    base.Dispose(disposing);
}

这篇关于我可以传递一个'using'上下文到c#中的另一个方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆