C# ef6中带有接口的存储库模式
aLets有一个简单的场景:C# ef6中带有接口的存储库模式,c#,entity-framework-6,repository-pattern,C#,Entity Framework 6,Repository Pattern,aLets有一个简单的场景: public interface IMember { string Name { get; set; } } public class MemberEF6Impl : IMember { //some annotations... public string Name { get; set; } } public class MemberVMImpl : IMember { //some other annotations...
public interface IMember
{
string Name { get; set; }
}
public class MemberEF6Impl : IMember
{
//some annotations...
public string Name { get; set; }
}
public class MemberVMImpl : IMember
{
//some other annotations...
public string Name { get; set; }
//some functionality...
}
在我们的程序中,我有两个具体的接口实现。一个实现专门用于数据库迁移,一个用于我们的viewmodel。现在我想实现工厂模式,并增加一个接口和两个具体的实现:
public interface IRepository
{
ICollection<TModel> GetAll<TModel>() where TModel : class;
//some more functionality...
}
public class RepositoryEF6Impl : IRepository
{
protected readonly DbContext context;
public RepositoryEF6Impl(DbContext context)
{
this.context = context;
}
public ICollection<TModel> GetAll<TModel>() where TModel : class
{
return context.Set<TModel>().ToList();
}
//some more functionality...
}
公共接口IRepository
{
ICollection GetAll(),其中TModel:class;
//更多功能。。。
}
公共类RepositoryEF6Impl:IRepository
{
受保护的只读DbContext上下文;
public RepositoryEF6Impl(数据库上下文)
{
this.context=上下文;
}
public ICollection GetAll(),其中TModel:class
{
返回context.Set().ToList();
}
//更多功能。。。
}
现在,我可以直接使用存储库,如下所示:
IRepository repo = new RepositoryEF6Impl(context);
repo.GetAll<MemberEF6Impl>();
i假定回购=新回购EF6impl(上下文);
repo.GetAll();
到目前为止还不错。但我想这样使用它:
IRepository repo = new RepositoryEF6Impl(context);
repo.GetAll<IMember>(); //note the difference
i假定回购=新回购EF6impl(上下文);
repo.GetAll()//注意区别
问题是数据库中没有IMember,而是MemberEF6Impl
我为什么要这样使用它:
IRepository repo = new RepositoryEF6Impl(context);
repo.GetAll<IMember>(); //note the difference
因为数据库和viewmodel有不同的具体类,所以我还必须为viewmodel创建第二个存储库,它只是具体的VMImpl类和EF6存储库之间的一个层
public class RepositoryVMImpl : IRepository
{
protected readonly IRepository repository;
public RepositoryVMImpl(IRepository repository)
{
this.repository = repository;
}
public ICollection<TModel> GetAll<TModel>() where TModel : class
{
return repository.GetAll<TModel>();
}
}
公共类RepositoryVMImpl:IRepository
{
受保护的只读存储库;
公共存储VMImpl(IRepository存储库)
{
this.repository=存储库;
}
public ICollection GetAll(),其中TModel:class
{
返回repository.GetAll();
}
}
有没有办法做到这一点?我的建议是使用单个存储库,但使用一些方法重载来投影请求的泛型类型 方法重载:
public ICollection<TProjection> GetAll<TModel, TProjection>(Expression<Func<TModel, TProjection>> projection)
{
return context.Set<TModel>().Select(projection).ToList();
}
public ICollection GetAll(表达式投影)
{
返回context.Set().Select(projection.ToList();
}
然后您可以使用这样的方法,它将提供对返回类型的控制
repository.GetAll<MemberEF6Impl, IMember>(memberEF => new MemberVMImp { ... })
repository.GetAll(memberEF=>newmembervmimp{…})
如果仍然需要EF实体模型作为结果类型,则可以使用当前方法:
repository.GetAll<MemberEF6Impl>();
repository.GetAll();
关于环境足迹预测的更多信息:
还提供了这样的功能-它可以为您节省一些时间。您应该查看它。视图模型或dto最好与域逻辑解耦