0

看完后,this question。我想我需要查看我的结构以避免多余的代码。如果我有一个Service类和IRepository,我需要一个存储库类吗?

我目前的结构是Controller - > Repository - > IRepository。

信息库看起来是这样的:

public class UserRepository : IUserRepository, IDisposable 
{ 
    private StudentSchedulingEntities _context; 

    public UserRepository(StudentSchedulingEntities context) 
    { 
     if (context == null) 
      throw new ArgumentNullException("context"); 

     _context = context; 
    } 
    public IEnumerable<User> GetUsers() 
    { 
     return _context.Users.ToList(); 
    } 
    public User GetUserByID(int id) 
    { 
     return _context.Users.Find(id); 

    } 
    public void InsertStudent(User user) 
    { 
     _context.Users.Add(user); 
    } 
    public void DeleteStudent(int userID) 
    { 
     User usr = _context.Users.Find(userID); 
     _context.Users.Remove(usr); 
    } 
    public void UpdateStudent(User user) 
    { 
     _context.Entry(user).State = EntityState.Modified; 
    } 
    public void Save() { 
     _context.SaveChanges(); 
    } 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_context != null) 
      { 
       _context.Dispose(); 
       _context = null; 
      } 
     } 
    } 
} 

我IRepository看起来是这样的:

public interface IUserRepository : IDisposable 
{ 
    IEnumerable<User> GetUsers(); 
    User GetUserByID(int userID); 
    void InsertStudent(User user); 
    void DeleteStudent(int userID); 
    void UpdateStudent(User user); 
    void Save(); 
} 

我想避免再次在服务层这样做。我是否需要存储库类或者是否应该实施服务层来替换存储库?

回答

2

您的服务层将不再需要任何资料库的实现,它只会使用存储库来查找用户,添加/编辑/删除用户,等等。现在

,如果我可以提供一点意见,我建议去一个通用的存储库。这样,如果您需要制作新的存储库,它非常简单。我们使用nopCommerce,和他们使用下面的代码:

public partial interface IRepository<T> where T : BaseEntity 
{ 
    T GetById(object id); 
    void Insert(T entity); 
    void Update(T entity); 
    void Delete(T entity); 
    IQueryable<T> Table { get; } 
} 

而且由于它使用实体框架,这是实现:

/// <summary> 
/// Entity Framework repository 
/// </summary> 
public partial class EfRepository<T> : IRepository<T> where T : BaseEntity 
{ 
    private readonly IDbContext _context; 
    private IDbSet<T> _entities; 

    /// <summary> 
    /// Ctor 
    /// </summary> 
    /// <param name="context">Object context</param> 
    public EfRepository(IDbContext context) 
    { 
     this._context = context; 
    } 

    public T GetById(object id) 
    { 
     return this.Entities.Find(id); 
    } 

    public void Insert(T entity) 
    { 
     try 
     { 
      if (entity == null) 
       throw new ArgumentNullException("entity"); 

      this.Entities.Add(entity); 

      this._context.SaveChanges(); 
     } 
     catch (DbEntityValidationException dbEx) 
     { 
      var msg = string.Empty; 

      foreach (var validationErrors in dbEx.EntityValidationErrors) 
       foreach (var validationError in validationErrors.ValidationErrors) 
        msg += string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine; 

      var fail = new Exception(msg, dbEx); 
      //Debug.WriteLine(fail.Message, fail); 
      throw fail; 
     } 
    } 

    public void Update(T entity) 
    { 
     try 
     { 
      if (entity == null) 
       throw new ArgumentNullException("entity"); 

      this._context.SaveChanges(); 
     } 
     catch (DbEntityValidationException dbEx) 
     { 
      var msg = string.Empty; 

      foreach (var validationErrors in dbEx.EntityValidationErrors) 
       foreach (var validationError in validationErrors.ValidationErrors) 
        msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); 

      var fail = new Exception(msg, dbEx); 
      //Debug.WriteLine(fail.Message, fail); 
      throw fail; 
     } 
    } 

    public void Delete(T entity) 
    { 
     try 
     { 
      if (entity == null) 
       throw new ArgumentNullException("entity"); 

      this.Entities.Remove(entity); 

      this._context.SaveChanges(); 
     } 
     catch (DbEntityValidationException dbEx) 
     { 
      var msg = string.Empty; 

      foreach (var validationErrors in dbEx.EntityValidationErrors) 
       foreach (var validationError in validationErrors.ValidationErrors) 
        msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); 

      var fail = new Exception(msg, dbEx); 
      //Debug.WriteLine(fail.Message, fail); 
      throw fail; 
     } 
    } 

    public virtual IQueryable<T> Table 
    { 
     get 
     { 
      return this.Entities; 
     } 
    } 

    private IDbSet<T> Entities 
    { 
     get 
     { 
      if (_entities == null) 
       _entities = _context.Set<T>(); 
      return _entities; 
     } 
    } 
     //TODO implement IDisposable interface 
} 

现在,它会像IRepository<User>IRepository<Whatever>一样简单。

+0

感谢您的回复。我有一个Generic Repository,但是我觉得我需要一个有子表的常规定制仓库。 (不太清楚如何实现)。所以我想,我应该实现服务层来处理。你是否碰巧知道可能会使我朝着正确方向发展的教程/文章? – xivo

+0

我同意,你的服务层应该处理该问题。真的,存储库非常笨 - 它应该只是获取和设置数据。在对数据做任何事情之前(例如,在将数据放入子表之前确保数据存在于父表中)之前,您的服务层就是要在其中进行检查和平衡的地方。至于教程,不幸的是我没有链接。我会看到我可以挖掘的东西。祝你好运! –

+0

这是一个有点薄,但它非常starightforward,所以希望它对你有一些价值:[链接](http://www.asp.net/mvc/tutorials/older-versions/models-(data)/验证-与一种服务层-CS) –

0

绝对没有冗余代码:-)当你说:

我现在的结构是控制器 - >库 - >

在控制器从库继承?你也不想要那样。存储库层通常连接到存储(XML,数据库,文件系统等)并映射到存储库友好的类。另一层管理存储库层到本地业务/服务类的映射。

相关问题