存储库模式中的数据库调用在哪里?

时间:2013-06-19 04:56:20

标签: design-patterns asp.net-web-api repository-pattern

我查看了几个存储库模式示例,但我似乎无法确定数据库访问的位置。我所看到的所有示例似乎都预期使用实体框架,这超出了我正在做的小项目的范围。我正在尝试创建一个具有5个左右模型/​​控制器的WebAPI服务。

基本上,我的问题是:如何将我的数据库调用集成到项目中?我应该直接从控制器调用DAL方法,这似乎是反模式的吗?控制器中的数据库上下文是如何使用示例中的EF完成的,但我不知道实际通过属性或构造函数传递给控制器​​的 where

编辑:

也许我不够清楚。我为此道歉。我没有使用实体框架。我没兴趣使用EF。我不会在我的项目中的任何一点使用它。

2 个答案:

答案 0 :(得分:3)

所以你必须直接使用ADO.NET,对吧?

这是一个样本回购:

public class UserRepository : Repository<User>
{
    public UserRepository(AdoNetContext context) : base(context)
    {
    }

    public void Create(User user)
    {
        using (var command = _connection.CreateCommand())
        {
            command.CommandText = @"INSERT INTO Users (CompanyId, FirstName) VALUES(@companyId, @firstName)";
            command.AddParameter("companyId", user.CompanyId);
            command.AddParameter("firstName", user.FirstName);
            command.ExecuteNonQuery();
        }

        //todo: Get identity. Depends on the db engine.
    }


    public void Update(User user)
    {
        using (var command = _connection.CreateCommand())
        {
            command.CommandText = @"UPDATE Users SET CompanyId = @companyId WHERE Id = @userId";
            command.AddParameter("companyId", user.CompanyId);
            command.AddParameter("userId", user.Id);
            command.ExecuteNonQuery();
        }
    }

    public void Delete(int id)
    {
        using (var command = _connection.CreateCommand())
        {
            command.CommandText = @"DELETE FROM Users WHERE Id = @userId";
            command.AddParameter("userId", id);
            command.ExecuteNonQuery();
        }
    }

    public IEnumerable<User> FindUsers(string firstName)
    {
        using (var command = _connection.CreateCommand())
        {
            command.CommandText = @"SELECT * FROM Users WHERE CompanyId = @companyId AND FirstName LIKE @firstName";
            command.AddParameter("companyId", LoggedInUser.companyId);
            command.AddParameter("firstName", firstName + "%");
            return ToList(command);
        }
    }    

    public IEnumerable<User> FindBlocked()
    {
        using (var command = _connection.CreateCommand())
        {
            command.CommandText = @"SELECT * FROM Users WHERE Status = -1";
            return ToList(command);
        }
    }    

    protected void Fill(IDataRecord record, User user)
    {
        user.FirstName = (string)record["FirstName"];
        user.Age = (int)record["Age"];
    }
}

来自我的ADO.NET, the right way文章。

答案 1 :(得分:1)

如果要在控制器中使用Entity Framework数据,则可以使用Inversion of Control容器框架将其传递给构造函数。框架将自动创建数据上下文的实例,然后WebApi控制器的实例传入刚刚创建的数据上下文。

这是一个允许这样做的框架示例:

http://nuget.org/packages/Autofac.WebApi/

https://code.google.com/p/autofac/w/list

编辑1:

如果您不想使用实体框架,那么采用相同的方法,但不是将数据上下文传递到WebApi控制器,而是可以传入ADO.NET连接。

编辑2:

您应该查看工作单元和存储库模式。工作单元负责管理数据库连接/数据上下文等,还将创建存储库的实例。然后,每个存储库将管理每个表中的实体以及您如何读取/更新这些实体。

然后我的初始响应适用,但它不是数据上下文,而是您的工作单元类的实例。

这些模式有很多很好的例子,并且在stackoverflow和互联网上使用Autofac,所以我不会在这里重复它们。请注意,我提到了Autofac,但可以使用任何支持ASP.NET WebApi的IoC容器。