我想通过访问数据库时添加另一层来改进.NET项目。这是我的代码:

namespace Company.Models
{
public static class AgencyBean
{
[WebMethod]
    [ScriptMethod(UseHttpGet = true)]
    public static String createGUID(string name)
    {
       DataAccess dataAccess = new DataAccess();
       bool exists = dataAccess.checkIfExists(Id);
       if(exist)
       {
           dataAccess.delete(Id);
       }
       retur "ok";
    }
 }
}


我将DataAccess类放在一个单独的文件夹“ Helpers”中,它包含我的大部分查询:

public class DataAccess
 {
public bool checkIfExists(String Id)
    {
        try
        {
            SqlConnection cnn = new SqlConnection(dataConnection);
            cnn.Open();
            SqlCommand check_Id = new SqlCommand("SELECT COUNT(*) FROM TABLE_GUID WHERE ([USER_ID] = @Id)", cnn);
            check_Id.Parameters.AddWithValue("@Id", Id);
            int UserExist = (int)check_Id.ExecuteScalar();

            if (UserExist > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (SqlException ex)
        {
            Debug.WriteLine("SQL Exception " + ex);
            DisplaySqlErrors(ex);
            throw ex;
        }
    }
 }

public class AgentBeanController : Controller
{
    // GET: AgentBean
    public ActionResult Index(string name)
    {
        return View();
    }

    [AllowAnonymous]
    [WebMethod]
    public string AgentURL()  //here we create Agent URL and return it to the view
    {
        string var = Models.AgentBean.createGUID("TODO");
        return var;
    }


}


我几乎以非常直接的方式访问数据库。更好的技术会如何呢,这样访问可以更安全,就像通过服务层访问一样?
我正在连接到某些服务器中的现有sql数据库,并在我的项目中使用MVC架构。

最佳答案

这就是我过去所做的事情。

首先,这就是您的“模型”命名空间...模型永远不应该具有数据库连接性。取而代之的是,您有一个单独的类(例如控制器)来充实一些模型。

其次,我有一个“服务”类,它连接到“存储库”类。存储库类实现了一个接口,以标识您正在使用的数据库的确切“类型”。但是,如果这不是您的要求的一部分,则可能不需要那么做。

第三,查找依赖项注入(又名DI)。有几个框架。我个人使用过Autofac,但也存在其他人来简化工作。

第四,在您的“控制器”,“服务”和“存储库”类上,实施依赖项注入以及形成合同所需的任何接口。

第五,我将使用一个实际的控制器名称空间,而不是在模型名称空间之外进行双向的HTTP调用。将其与数据混合,然后将该模型返回给您。

基本上,在这样的场景中,您试图使每个组件都按照指定的方式执行...将职责分解为较小的部分,并专注于此。您的控制器应该只是“获取”您的模型,并可能根据需要或任何其他业务类型的逻辑对其进行一些转换。
您的服务应处理控制器与数据库层之间的通信。
您的数据访问层(例如,在这种情况下,某些“存储库”类...)将完成所有这些新的数据连接和/或设置对存储过程或查询的调用。

用这种方式做事有很多好处。一些重要的方面是可维护性,可读性和代码重用。当然,就文件放置在任何地方而言,这会使您的项目变得更加复杂……但这可能是一件好事。这比将所有内容都扔进一个类并让它执行所有操作要好得多:)

但是,仅供参考,这是我过去完成的实现...我相信还有更好的方法,但是这种设置对我和我的团队都非常有效。

这是一个使用您发布的一些代码的小示例。我没有检查错别字,也不会编译,但应该有助于大致了解我在说什么...。

namespace Company.Models
{
    public class AgencyBean
    {
        public AgencyName{get;set;}
        public AgencyId{get;set;}
        // other properties...
    }
}




namespace Company.Controllers
{
    public class MyController : Controller
    {
        private readonly IMyService myService;


        public MyController(IMyService myService) // <-- this is your dependency injection here...
        {
            this.myService = myService;
        }

        [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public static String createGUID(string name)
        {
            var model = new AgencyBean();
            model.AgencyId = 1;
            model = myService.getAgency(agencyBean);
            return model;
        }
    }
}




namespace Company.Services
{
    public class MyService
    {
        private readonly IMyRepository myRepository;


        public MyService(IMyRepository myRepository) // <-- this is your dependency injection here...
        {
            this.myRepository = myRepository;
        }

        public AgencyBean getAgency(AgencyBean model){
            var dataTable = myRepository.getAgencyData(model.AgencyId);
            // fill other properties of your model you have...
            // ...
            // ...
            return model;
        }
    }
}



namespace Company.Repositories
{
    public class MyRepository : IDatabaseCommon  // <-- some interface you would use to ensure that all repo type objects get connection strings or run other necessary database-like setup methods...
    {
        private readonly String connectionString{get;set;}

        public MyRepository()
        {
            this.connectionString = //get your connection string from web.config or somewhere else...;
        }

        public DataTable getAgencyData(int id){
            var dataTable = new DataTable();

            // perform data access and fill up a data table

            return dataTable;
        }
    }
}

10-04 20:54
查看更多