8

由于平台限制,我试图使用ado.net实现存储库模式。使用旧ado.net实现通用存储库模式

public interface IGenericRepository<T> : IDisposable where T : class 
{ 
    IQueryable<T> GetAll(); 
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate); 
    void Add(T entity); 
    void Delete(T entity); 
    void Edit(T entity); 
    void Save(); 
} 

如何完成以下抽象类...?

public abstract class GenericRepository<C, T> : 
    IGenericRepository<T> 
    where T : class 
    where C : IDbDataAdapter, new() 
{ 

    private C dbDataAdapter = new C(); 
    protected C DB 
    { 
     get { return dbDataAdapter; } 
     set { dbDataAdapter = value; } 
    } 

    public virtual IQueryable<T> GetAll() 
    { 
     DataTable dt; 
     dbDataAdapter.fill(dt); 
     IQueryable<T> query = dt....?; 
     return query; 
    } 

    public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate) 
    { 

     IQueryable<T> query = dbDataAdapter.???Set<T>???().Where(predicate); 
     return query; 
    } 

更新:
我将用固有的这两个接口/类之后实现指定的域库。

public class FooRepository : 
    GenericRepository<FooBarEntities, Foo>, IFooRepository { 

    public Foo GetSingle(int fooId) { 

     var query = GetAll().FirstOrDefault(x => x.FooId == fooId); 
     return query; 
    } 
} 

回答

0

您正试图构建典型的OR映射器所做的一部分。这是一个lot的工作。为什么不使用ORM?

+1

同意。有大量的ORM可用。 –

+1

我为传统应用程序添加了功能,并且不想携带任何新的DLL。 – ca9163d9

+1

好的,那么你有一个人的工作要做,以实现FindBy方法。您需要从表达式创建SQL字符串。这不是微不足道的*。我建议你改变你的界面的设计,以不支持任意表达式。也许你可以支持where-select-orderby-top序列。也许这就够了。 – usr

6

有一个通用的存储库通常不是一个好主意。存储库是一个重要的领域概念,你不想过度概括它,就像你不想概括你的实体。通用存储库是CRUDy,并将焦点从您的域转移。请考虑this article by Greg Young

相关提示,揭露IQueryable的除了会推出tight coupling使您的代码少数据驱动。

+0

我已更新问题以解释域/数据驱动问题。 – ca9163d9

0

如果你从一个充满不一致性的遗留数据库和大量的存储过程开始,并试图将它连接到一个ORM/Repository模式,那么你可能会发现自己非常沮丧通用存储库模式。

我知道通用存储库模式在教程部分这些天是很受欢迎的,当很多较新的应用程序让像Entity Framework和Active Record这样的数据库创建数据库时(记住这种风格意味着没有存储过程或最少使用它们) 。在这些较新的场景中,数据往往会更清晰一些,并且使得将它连接到某个通用存储库模式非常容易,因为每个实体都有一个ID。

0

不太上的话题,但我有类似的问题,这里是我的解决方案(谁能帮助)

创建Identity类:

public class Identity 
    { 
     public int Id { get; set; } 
    } 

创建entyty类:

public class Employee: Identity 
    { 
     public string Name { get; set; } 
     public string Surname { get; set; } 
     public int Age { get; set; } 
    } 

版本库界面(也可以只使用抽象类):

interface IRepository<T> where T: Identity 
    { 
     T GetById(int id); 
     ICollection<T> GetAll(); 
     ICollection<T> GetAll(string where); 
     void Update(T entity); 
     void Insert(T entity); 
     bool Delete(T entity); 
     bool Delete(ICollection<T> entityes); 
    } 

创建通用抽象类:

public abstract class AbstractRepository<T>: IRepository<T> where T : Identity 
    { 
     protected abstract string TableName { get; } 

     protected abstract T DataRowToModel(DataRow dr); 

     protected virtual ICollection<T> DataTableToCollection(DataTable dt) 
     { 
      if (dt == null) 
      { 
       return null; 
      } 
      return dt.AsEnumerable().Select(x => DataRowToModel(x)).ToList(); 
     } 

     public virtual T GetById(int id) 
     { 
      var query = $"select * from {TableName} where id = {id}"; 
      //the data access layer is implemented elsewhere 
      DataRow dr = DAL.SelectDataRow(query); 
      return DataRowToModel(dr); 
     } 

     public virtual void Delete(T entity) 
     { 
      if (entity.Id == 0) 
      { 
       return; 
      } 
      var query = $"delete from {TableName} where id = {entity.Id}"; 
      DAL.Query(query); 
     } 

     public virtual void Delete(ICollection<T> entityes) 
     { 
      var collectionId = IdentityCollectionToSqlIdFormat(entityes); 
      if (string.IsNullOrEmpty(collectionId)) 
      { 
       return; 
      } 
      var query = $"delete from {TableName} where id in ({collectionId})"; 
      DAL.Query(query); 
     } 

     public virtual ICollection<T> GetAll() 
     { 
      var query = $"select * from {TableName}"; 
      DataTable dt = DAL.SelectDataTable(query); 
      return DataTableToCollection(dt); 
     } 

     public virtual ICollection<T> GetAll(string where) 
     { 
      var query = $"select * from {TableName} where {where}"; 
      DataTable dt = DAL.SelectDataTable(query); 
      return DataTableToCollection(dt); 
     } 

     protected virtual string IdentityCollectionToSqlIdFormat(ICollection<T> collection) 
     { 
      var array = collection.Select(x => x.Id); 
      return string.Join(",", array); 
     } 

     public abstract bool Update(T entity); 
     public abstract bool Insert(T entity); 
    } 

并实行EmployeeRepository:

public class EmployeeRepository : AbstractRepository<Employe> 
    { 
     protected sealed override string TableName 
     { 
      get 
      { 
       return "dbo.Employees"; 
      } 
     } 

     protected sealed override Employe DataRowToModel(DataRow dr) 
     { 
      if (dr == null) 
      { 
       return null; 
      } 
      return new Employe 
      { 
       Id = dr.Field<int>("id"), 
       Name = dr.Field<string>("name"), 
       Surname = dr.Field<string>("surname"), 
       Age = dr.Field<int>("age") 

      }; 
     } 


     public override void Insert(Employe entity) 
     { 
      var query = [email protected]"insert into {TableName} (name, surname, age) 
          values({entity.Name},{entity.Surname},{entity.Age})"; 
      DAL.Query(query); 
     } 

     public override bool Update(Employe entity) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

仅此而已。在代码中使用:

public class SomeService 
{ 
    public void SomeeMethod() 
    { 
    int employeeId = 10; // for example 
    EmployeeRepository repository = new EmployeeRepository(); 
    Employee employee = repository.GetById(employeeId); 
    repository.Delete(employee); 
    //... 
    } 
    } 
相关问题