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 string Name { get; set; }
//some functionality...
}我有两个在我们的程序中的所有接口的具体实现。一个实现,特别是数据库迁移,一个为我们的视图模型。现在,我想实现factory-pattern,并增加一个接口和两个具体的实现:
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 repo = new RepositoryEF6Impl(context);
repo.GetAll<MemberEF6Impl>();到目前一切尚好。但我想用这个方法:
IRepository repo = new RepositoryEF6Impl(context);
repo.GetAll<IMember>(); //note the difference问题是数据库中没有IMember,只有一个MemberEF6Impl。
为什么我想用这种方式:
因为对于数据库和视图模型,我们有不同的具体类,所以我必须为视图模型创建第二个存储库,它只是具体的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>();
}
}有办法做到这一点吗?
发布于 2017-09-19 14:23:19
我的建议是使用单个存储库,但使用某种方法重载以突出所请求的泛型类型。
方法过载:
public ICollection<TProjection> GetAll<TModel, TProjection>(Expression<Func<TModel, TProjection>> projection)
{
return context.Set<TModel>().Select(projection).ToList();
}然后您可以使用这样的方法,它将控制返回类型。
repository.GetAll<MemberEF6Impl, IMember>(memberEF => new MemberVMImp { ... })如果仍然需要EF实体模型作为结果类型,则可以使用当前方法:
repository.GetAll<MemberEF6Impl>();有关EF预测的更多信息:https://www.tektutorialshub.com/projection-queries-entity-framework/
此外,自动机还提供了这样的功能--它可以节省您一些时间。你应该去看看。
https://stackoverflow.com/questions/46302475
复制相似问题