cul*_*rer 3 .net c# generics entity-framework interface
我正在尝试实现一个完全通用的CRUD API,通过上下文可以传入任何类类型并通常保存,更新等.
我有一个存储库,可以保存任何模型类型,如下所示:
public class Repository<T> : IRepository<T> where T : class
{
private Context _db = new Context();
public T Add(T newItem)
{
var result = _db.Set<T>().Add((T)newItem);
_db.SaveChanges();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
这继承自实现所有"add"方法的通用接口:
public interface IRepository<T> where T : class
{
T Add(T newItem);
}
Run Code Online (Sandbox Code Playgroud)
我很难理解为什么我不能将泛型类型传递给存储库接口的新实例?我理想的喜欢这样的东西:
var data = new Data(){
Id = 1
};
IRepository<data.GetType()> repo = new Repository<data.GetType()>();
Run Code Online (Sandbox Code Playgroud)
从而允许我将任何类型传递给方法并在其后面生成正确的接口.
它允许我传递一种具体的类型,但这种类型会使其成为通用的对象.
任何关于这个的想法或解释为什么它不可能将不胜感激 - 谢谢.
尝试在自身上实现具有泛型参数的通用存储库IRepository没有意义,因为术语泛型(在这种情况下)不是指CLR泛型,而是指存储库的性质,即使用不同类型的能力使用相同存储库实例的实体,与每个类型的存储库方法(ProductsRepository例如)相比.
将泛型参数放在方法上可以轻松解决问题:
public interface IRepository
{
T GetById<T>(object id);
IEnumerable<T> Get<T>(Expression<Func<T, bool>> criteria);
T Add<T>(T data);
}
Run Code Online (Sandbox Code Playgroud)
使用EntityFramework可能的实现方式是:
public class EntityFrameworkRepository : IRepository
{
public T GetById<T>(object id)
{
return this.Set<T>().Find(id);
}
public IEnumerable<T> Get<T>(Expression<Func<T, bool>> criteria)
{
return this.Set<T>().Where(criteria);
}
public T Add<T>(T data)
{
this.Set<T>().Add(data);
return data;
}
}
Run Code Online (Sandbox Code Playgroud)