我正在考虑两个IRepository接口中的一个,一个是IQueryable的后代,另一个是IQueryable.
像这样:
public interface IRepository<T> : IQueryable<T>
{
T Save(T entity);
void Delete(T entity);
}
Run Code Online (Sandbox Code Playgroud)
或这个:
public interface IRepository<T>
{
T Save(T entity);
void Delete(T entity);
IQueryable<T> Query();
}
Run Code Online (Sandbox Code Playgroud)
LINQ用法是:
from dos
in ServiceLocator.Current.GetInstance<IRepository<DomainObject>>()
where dos.Id == id
select dos
Run Code Online (Sandbox Code Playgroud)
要么...
from dos
in ServiceLocator.Current.GetInstance<IRepository<DomainObject>>().Query
where dos.Id == id
select dos
Run Code Online (Sandbox Code Playgroud)
我有点像第一个,但是模拟是有问题的.其他人如何实现LINQable,可模拟的存储库?
假设您在LINQ类中定义了以下实体:
Product
Customer
Category
Run Code Online (Sandbox Code Playgroud)
我应该为所有人拥有一个存储库类:
StoreRepository
Run Code Online (Sandbox Code Playgroud)
......或者我应该:
ProductRepository
CustomerRepository
CategoryRepository
Run Code Online (Sandbox Code Playgroud)
每个人的利弊是什么?就我而言,我的解决方案中有几个"应用程序"...... Store应用程序只是其中之一.
将数据库实体映射到模型和执行业务逻辑的最佳实践是什么?我已经看到两者的实现差异很大.我注意到了许多实现,其中Repository(在数据层中)本身负责将数据库实体映射到域模型.例如,一个可以执行此操作的存储库:
public IQueryable<Person> GetPersons()
{
return DbSet.Select(s => new Person
{
Id = s.Id,
FirstName= s.FirstName,
Surname= s.Surname,
Location = s.Location,
});
}
Run Code Online (Sandbox Code Playgroud)
但是在N Tier设计上全面搜索SO时,我注意到虽然没有银弹,但在大多数情况下,建议手动或使用Mapper在MVC项目中执行控制器内的映射.还有人重申,服务层永远不应该执行映射,并且它应该负责执行业务逻辑.这里有几个问题:
Personenities 的全名,或者将所有Persons 的年龄增加10年,应该在哪里执行此操作.在模型本身?例如,我会FullName在模型上有一个属性来计算全名和年龄吗?或者我在服务层内定义一些服务来执行业务逻辑?编辑
哇这么多亲密的选票.道歉,我没有全面搜索.我在这里提出的"在哪里执行业务逻辑"问题已经可以在SO和其他地方找到(虽然有时会有些隐晦地传达):
但是我还没有找到我所遇到的映射问题的标准解决方案,而且我想我也许可以更有说服力地表达我的问题.因此,普遍的共识似乎是业务逻辑进入服务层,将域模型映射到视图模型应该在控制器/表示层中进行.并且由于建议不要将数据库实体映射到数据层以外的任何层,因此建议您手动或通过映射器(如Auto Mapper)将实体映射到数据层的域模型(这是我从阅读很多文章).我的困惑源于将实体映射到域模型以及将域模型映射到视图模型的问题.然而,正如我之前提到的,我可以更清楚地表达我的问题.我混淆的原因是我已经读过,映射实体到域模型应该在控制器中发生,这应该改为说"将实体映射到域模型应该在以后的数据中发生,并将域模型映射到视图模型应该在控制器中进行.
我想我已经达到了"分析瘫痪"的状态.我有一个MVC应用程序,使用EF作为ORM.所以我正在尝试决定最好的数据访问模式,到目前为止我认为将所有数据访问逻辑放入控制器是要走的路......但它听起来有点不对劲.另一种选择是创建外部存储库,处理数据交互.这是我的利弊:
如果嵌入数据访问控制器,我将得到这样的代码:
using (DbContext db = new DbContext())
{
User user = db.Users.Where(x=>x.Name == "Bob").Single();
user.Address.Street = "some st";
db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
所以有了这个,我得到了延迟加载的全部好处,我在完成后立即关闭连接,我对where子句的灵活性 - 所有的细节.con - 我在一个方法中混合了一堆东西 - 数据检查,数据访问,UI交互.
使用Repository,我正在外部化数据访问,理论上,如果我决定使用ado.net或使用不同的数据库,则可以替换repos.但是,我没有看到实现延迟加载的良好清洁方式,以及如何控制DbContext /连接的生命周期.说,我有CRUD方法的IRepository接口,我如何加载属于给定用户的地址列表?像GetAddressListByUserId这样的方法看起来很丑陋,错误,并且会让我创建一堆同样丑陋的方法,并且在使用ORM时没什么意义.
我确信这个问题已经解决了几百万次,希望有一个解决方案..
关于存储库模式的另一个问题 - 如何处理属性对象?例如,用户有一个地址列表,您将如何检索该列表?为地址创建存储库?使用ORM,地址对象不必具有回复用户的引用,也不需要具有repo的Id字段 - 它必须拥有所有这些.更多代码,更多暴露属性..