[英]Implement a generic repository pattern using old 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;
}
}
擁有通用存儲庫通常不是一個好主意。 存儲庫是一個重要的域概念,您不希望過度概括它,就像您不想概括您的實體一樣。 通用存儲庫是CRUDy,將焦點從您的域轉移。 請考慮Greg Young的這篇文章 。
在相關的說明中,除了使代碼更少域和更多數據驅動之外,公開IQueryable還會引入緊耦合 。
您正在嘗試構建典型OR映射器的一部分。 這是很多工作。 為什么不使用ORM?
如果你要從一個充滿不一致性的遺留數據庫,以及大量的存儲過程,並且你試圖將它連接到ORM / Repository模式,那么你可能會發現自己對實現Generic Repository模式感到非常沮喪。
我知道Generic Repository模式在教程部分中是一個巨大的打擊,當時很多新的應用程序讓像Entity Framework和Active Record這樣的東西構成了數據庫(記住這種風格意味着沒有存儲過程或它們的最小用途)。 在這些較新的場景中,數據往往更加清晰,並且很容易將其連接到一些通用的存儲庫模式,因為每個實體都有一個ID。
不是主題,但我有類似的問題,這是我的解決方案(任何人都可以幫助)
創建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 = $@"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);
//...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.