asp.net mvc的良好存储库模式

ACP*_*ACP 3 asp.net-mvc repository-pattern

我已经在我的asp.net mvc web应用程序中实现了一个存储库模式......但是我想知道这是一个很好的存储库模式还是我还能改进它...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TaxiMVC.BusinessObjects;

namespace TaxiMVC.Models
{
    public class ClientRepository
    {
        private TaxiDataContext taxidb = new TaxiDataContext();
        Client cli = new Client();

        //Get all Clients
        public IQueryable<ClientBO> FindAllClients(int userId)
        {
            var client = from c in taxidb.Clients
                         where c.CreatedBy == userId && c.IsDeleted == 0 
                         select new ClientBO()
                         {
                             ClientId = c.ClientId,
                             ClientName= c.ClientName,
                             ClientMobNo= Convert.ToString(c.ClientMobNo),
                             ClientAddress= c.ClientAddress
                         };
            return client;
        }

        //Get Client By Id
        public ClientBO FindClientById(int userId,int clientId)
        {
            return (from c in taxidb.Clients
                    where c.CreatedBy == userId && c.ClientId == clientId && c.IsDeleted == 0
                         select new ClientBO()
                         {
                             ClientId = c.ClientId,
                             ClientName= c.ClientName,
                             ClientMobNo= Convert.ToString(c.ClientMobNo),
                             ClientAddress= c.ClientAddress
                         }).FirstOrDefault();
        }

        //Insert a new client
        public bool ClientInsert(ClientBO clientBO)
        {
            cli.ClientName = clientBO.ClientName;
            cli.ClientMobNo = Convert.ToInt64(clientBO.ClientMobNo);
            cli.ClientAddress = clientBO.ClientAddress;
            cli.CreatedDate = clientBO.CreatedDate;
            cli.IsDeleted = clientBO.IsDeleted;
            cli.CreatedBy = clientBO.CreatedBy;

            if (!taxidb.Clients.Where(c => c.ClientMobNo == cli.ClientMobNo).Any())
            {
                taxidb.Clients.InsertOnSubmit(cli);
                taxidb.SubmitChanges();
                return true;
            }
            else
                return false;
        }

      //Client Update
        public ClientBO updateClient(ClientBO clientBO)
        {
            var table = taxidb.GetTable<Client>();
            var cli = table.SingleOrDefault(c => c.ClientId == clientBO.ClientId && c.CreatedBy==clientBO.CreatedBy);
            cli.ClientName = clientBO.ClientName;
            cli.ClientMobNo = Convert.ToInt64(clientBO.ClientMobNo);
            cli.ClientAddress = clientBO.ClientAddress;
            taxidb.SubmitChanges();
            return clientBO;
        }

        //Delete Clients
        public bool deleteClients(string Ids, int userId)
        {
            var idsToDelete = Ids.Split(',').Select(c => Convert.ToInt32(c));
            var clientsToDelete = taxidb.Clients.Where(c => idsToDelete.Contains(c.ClientId));
            foreach (var client in clientsToDelete)
            {
                client.IsDeleted = Convert.ToByte(1); 
            }
            taxidb.SubmitChanges();
            return true;
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

和我的ClientBo.cs,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TaxiMVC.BusinessObjects
{
    public class ClientBO
    {
        public int ClientId { get; set; }
        public string ClientName { get; set; }
        public string ClientMobNo { get; set; }
        public string ClientAddress { get; set; }
        public DateTime CreatedDate { get; set; }
        public byte IsDeleted { get; set; }
        public int CreatedBy { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有在这里实现一个IRepository ...我应该实现它还是我的存储库仍然可以改进...任何建议....

Ala*_*tts 15

嗯,我肯定会采取一些措施来改善这一点.

第一: 我将为您的存储库定义一个接口来实现.这允许您更好地控制依赖性,并且当与控制/依赖性注入反转(IOC/DI)框架结合时,这得到了极大的改进.IOC/DI框架包括StructureMap或NInjet.从Scott Hanselman那里读到这个,这是一个非常全面的列表.

您的界面可能如下所示:

public interface IClientRepository
{
    IQueryable<ClientBO> FindAllClients(int userId);
    ClientBO FindClientById(int userId, int clientId);
    ClientInsert(ClientBO clientBO);
    ClientBO updateClient(ClientBO clientBO);
    bool deleteClients(string Ids, int userId);
}
Run Code Online (Sandbox Code Playgroud)

第二:不要将您的Business Object ClientBO(Client)转换为存储库内的持久对象()转换.这意味着如果您对BO进行任何更改,那么您将需要通过并更改整个存储库.

我注意到你有很多左右分配代码,例如.

cli.ClientName = clientBO.ClientName;
Run Code Online (Sandbox Code Playgroud)

我会认真研究AutoMapper的使用.它使这个"猴子代码"变得更加容易.

编辑:这是一篇博客文章,描述了如何使用AutoMapper删除左右分配代码.

第三:您的命名结构遍布整个商店.我们有:FindAllClients(),ClientInsert(),updateClient()都在一个班.命名非常差.对于您的存储库,尝试根据数据库端发生的情况对方法进行建模.尝试AddInsert,Delete,FindAllGetAll,FindGetAll,SaveChanges,方法名.

不要将类型追加/添加到方法名称中,就像你在里面一样ClientRepository,这意味着你将要添加或获取Client.

第四: 混合LINQ语法.在某些地方,您使用声明性查询语法,而其他地方使用方法语法.选择1并随处使用.

第五:这条线让我担心:

 if (!taxidb.Clients.Where(c => c.ClientMobNo == cli.ClientMobNo).Any())
Run Code Online (Sandbox Code Playgroud)

对我来说,这看起来很像商业逻辑.不是应该在存储库中的东西.将列声明为UNIQUEDB,或将该逻辑移动到另一个验证层.

这些是我跳出来的主要事情.其中一些是个人偏好,但我希望这会有所帮助.

  • @David Neale,我个人认为在一个类中对LINQ语法有多种变化是令人困惑的,但我不能理解它. (2认同)