我正在构建一个详细的here服务存储库模式的新项目。它似乎在最基本的例子中运作良好。在更复杂的场景中,可以在service \ repository层中混合对象吗?例如,假设有一个用户存储库和服务,我希望能够为创建用户创建审计,我认为这将在服务层中进行。
如果我遵循该文章,该服务会自动在构造函数中创建用户存储库对象。添加审计意味着将审计CRUD方法添加到用户存储库?这样做有意义吗?
public UserService(IValidationDictionary validationDictionary, IUserRrepository repository)
{
_validatonDictionary = validationDictionary;
_repository = repository;
}
答案 0 :(得分:3)
根据我的经验,您不需要每种实体类型的存储库。只需为整个模型创建一个存储库,然后对其使用linq查询。 EF已经提供了该存储库的实现,您可以创建如下所示的自定义接口,并在该存储库上实现它。
public interface IDataContext
{
void Add<T>(T entity) where T : BaseEntity;
void Delete<T>(T entity) where T : BaseEntity;
IQueryable<T> Find<T>(Expression<Func<T, bool>> where) where T : BaseEntity;
int SaveChanges()
}
您的基本实体是所有存储库的基类。
你要编写的linq的大部分内容都非常简单,但对于复杂的linq,只需编写实用程序类
在我们的实现中,从DbContext派生的类实现了这个接口,所有的审计都是通过使用ChangeTracker的保存方法完成的
EF 4.2的示例实现如下......
public class MyContext : DbContext, IDataContext
{
static MyContext ()
{
Database.SetInitializer<MyContext >(null);
}
public T GetById<T>(int id) where T : BaseEntity
{
return this.Set<T>().SingleOrDefault(i => i.Id == id);
}
public void Add<T>(T entity) where T : BaseEntity
{
this.Set<T>().Add(entity);
}
public void Delete<T>(T entity) where T : BaseEntity
{
this.Set<T>().Remove(entity);
}
public IQueryable<T> Find<T>(System.Linq.Expressions.Expression<Func<T, bool>> where) where T : BaseEntity
{
return this.Set<T>().Where(where);
}
public override int SaveChanges()
{
this.SetAuditValues();
return base.SaveChanges();
}
private void SetAuditValues()
{
var addedEntries = this.ChangeTracker.Entries().Where(e => e.State == System.Data.EntityState.Added);
var currentUser = this.GetCurrentUser();
foreach (var addedEntry in addedEntries)
{
var entity = addedEntry.Entity as BaseEntity;
if (entity != null)
{
entity.CreateDateTime = DateTime.Now;
entity.CreateUser = currentUser;
entity.ModDateTime = DateTime.Now;
entity.ModUser = currentUser;
}
}
var modifiedEntries = this.ChangeTracker.Entries().Where(e => e.State == System.Data.EntityState.Modified);
foreach (var modEntry in modifiedEntries)
{
var entity = modEntry.Entity as BaseEntity;
if (entity != null)
{
entity.ModDateTime = DateTime.Now;
entity.ModUser = currentUser;
}
}
}
}
答案 1 :(得分:1)
如果它属于该服务的目的或域,您肯定可以让一个存储库/服务层处理多个实体。通常在简单的示例中 - 您是正确的,您没有看到这一点,但没有理由可以包含其他实体。
现在关于您的审计,为什么不调用您的审计服务层而不是包括审计对象(如果那就是您的意思)