c# - 我可以将 'using' 上下文传递给 c# 中的另一个方法吗?

标签 c# linq entity-framework database-connection

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

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

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;
}

我想将其分成可重用的代码块,(并使我的控​​制器更小),就像这样

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();
    }
}

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

有什么方法可以将上下文传递给方法,就像这样

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();
}

是否可以这样做,以便我既可以分离出我的代码,又可以使用尽可能少的数据库连接?

最佳答案

我会首先朝着服务类的方向发展。所以你可以有一个像这样的新类:

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
    }
}
}

然后你的 Controller 将如下所示

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

然后我希望引入用于数据访问的存储库。 然后,UserService 将迁移到如下所示的内容:

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 将迁移到如下所示的内容:

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
        }
    }

Controller 将迁移到此:

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);
}

关于c# - 我可以将 'using' 上下文传递给 c# 中的另一个方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19980477/

相关文章:

c# - 如何直接在 .NET 代码中快速创建虚拟图像

C# Task Parallel Library 第一次慢

c# - EF Eager 获取派生类

c# - 如何在 Entity Framework 查询中初始化一个空列表?

linq - 动态地将类型传递给方法<T>

javascript - 如何将 Entity Framework 数据设置为 JavaScript 变量?

c# - 如何以编程方式在 aspx 文件中设置控件的属性?

C# Linq GroupBy,获取每个组中的列列表

c# - 使用 .DefaultIfEmpty() 而不是 .FirstOrDefault() ??字符串.空;

c# - LINQ 与嵌套循环