【问题标题】:What is DbContext doing in ADO.NETDbContext 在 ADO.NET 中做什么
【发布时间】:2017-07-24 11:52:03
【问题描述】:

我有代码可以连接到数据库并执行 CRUD 操作

请看下面的代码:

我们在代码中使用了“DbContext”。 它是通用的,可以与各种数据库一起使用,还是为 SQLServer 设计的?它的目的/使命是什么?

我以为 DBContext 只用于实体框架

public class UserRepository : Repository<User>
{
    private DbContext _context;
    public UserRepository(DbContext context)
        : base(context)
    {
        _context = context;
    }


    public IList<User> GetUsers()
    {
        using (var command = _context.CreateCommand())
        {
            command.CommandText = "exec [dbo].[uspGetUsers]";

            return this.ToList(command).ToList();
        }
    }

    public User CreateUser(User user)
    {
        using (var command = _context.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "uspSignUp";

            command.Parameters.Add(command.CreateParameter("@pFirstName", user.FirstName));
            command.Parameters.Add(command.CreateParameter("@pLastName", user.LastName));
            command.Parameters.Add(command.CreateParameter("@pUserName", user.UserName));
            command.Parameters.Add(command.CreateParameter("@pPassword", user.Password));
            command.Parameters.Add(command.CreateParameter("@pEmail", user.Email));

            return this.ToList(command).FirstOrDefault();


        }

    }


    public User LoginUser(string id, string password)
    {
        using (var command = _context.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "uspSignIn";

            command.Parameters.Add(command.CreateParameter("@pId", id));
            command.Parameters.Add(command.CreateParameter("@pPassword", password));

            return this.ToList(command).FirstOrDefault();
        }
    }


    public User GetUserByUsernameOrEmail(string username, string email)
    {
        using (var command = _context.CreateCommand())
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = "uspGetUserByUsernameOrEmail";

            command.Parameters.Add(command.CreateParameter("@pUsername", username));
            command.Parameters.Add(command.CreateParameter("@pEmail", email));

            return this.ToList(command).FirstOrDefault();
        }
    }


}

这里是 DbContext 类:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DataAccessLayer
{
    public class DbContext
    {


        private readonly IDbConnection _connection;
        private readonly IConnectionFactory _connectionFactory;
        private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
        private readonly LinkedList<AdoNetUnitOfWork> _uows = new LinkedList<AdoNetUnitOfWork>();

        public DbContext(IConnectionFactory connectionFactory)
        {
            _connectionFactory = connectionFactory;
            _connection = _connectionFactory.Create();
        }

        public IUnitOfWork CreateUnitOfWork()
        {
            var transaction = _connection.BeginTransaction();
            var uow = new AdoNetUnitOfWork(transaction, RemoveTransaction, RemoveTransaction);

            _rwLock.EnterWriteLock();
            _uows.AddLast(uow);
            _rwLock.ExitWriteLock();

            return uow;
        }

        public IDbCommand CreateCommand()
        {
            var cmd = _connection.CreateCommand();

            _rwLock.EnterReadLock();
            if (_uows.Count > 0)
                cmd.Transaction = _uows.First.Value.Transaction;
            _rwLock.ExitReadLock();

            return cmd;
        }

        private void RemoveTransaction(AdoNetUnitOfWork obj)
        {
            _rwLock.EnterWriteLock();
            _uows.Remove(obj);
            _rwLock.ExitWriteLock();
        }

        public void Dispose()
        {
            _connection.Dispose();
        }
    }
}

【问题讨论】:

    标签: c# asp.net-mvc entity-framework asp.net-mvc-4 model-view-controller


    【解决方案1】:

    我以为 DBContext 只用于实体框架

    你说得对,DBContext 是一个 EntityFramework 类,它结合了工作单元和存储库模式。

    但是,您似乎有一个使用 ado.net 创建的自定义 DBContext。不过,我不会真正称它为 DBContext。因为通常 DBContext 遵循 ObjectContext 的概念,即在上下文中引用域对象。这个特殊的自定义类更像是一个 DbCommand 工厂。

    它是通用的并且可以与各种数据库一起使用还是为 SQLServer[...] 设计的?

    它不是特定于 SQL 服务器的。因此它可以与其他数据库一起使用,如 Oracle 数据库、Microsoft SQL Server、MySQL、PostgreSQL、SQLite 等。但是,这将取决于每个数据库的正确配置和正确的查询使用。例如,对于所有数据库,参数并不总是以 @ 为前缀。但是,这个特殊的 DBContext 将该问题传递给调用它的类,并避免处理它,正如我们在 UserRepository 对类的使用中看到的那样。

    ...它的目的/使命是什么?

    您向我们展示的 DBContext 的目的是使用工厂获取连接,实例化并返回带有可选事务的 DBCommand。而且,Repository 基类函数 ToList 似乎负责执行 Command 并映射对象 User。

    看起来这是尝试使用 ado.net 创建存储库模式。而且,由于不知道您的应用程序的历史,我只能假设已做出避免使用实体框架的决定。我见过很多不同的方法。而且,很多人会争论正确的实施方式。但是,我认为这超出了这个特定问题的范围。

    【讨论】:

      【解决方案2】:

      您可以将 EntityFramework 用于execute raw SQL,但看起来您的示例中的DbContext 不是来自 EntityFramework 的。它可以是您项目中的其他库或自定义实现。您应该能够通过检查 using 导入或导航到 DbContext 定义来判断这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        • 1970-01-01
        • 2016-03-30
        • 2011-07-17
        • 2016-04-14
        • 2014-07-23
        • 2011-08-21
        相关资源
        最近更新 更多