asp.net mvc存储​​库模式与服务层,何时混合存储库中的实体?

时间:2011-11-18 18:16:10

标签: asp.net-mvc-3 entity-framework repository-pattern

我正在构建一个详细的here服务存储库模式的新项目。它似乎在最基本的例子中运作良好。在更复杂的场景中,可以在service \ repository层中混合对象吗?例如,假设有一个用户存储库和服务,我希望能够为创建用户创建审计,我认为这将在服务层中进行。

如果我遵循该文章,该服务会自动在构造函数中创建用户存储库对象。添加审计意味着将审计CRUD方法添加到用户存储库?这样做有意义吗?

    public UserService(IValidationDictionary validationDictionary, IUserRrepository repository)
    {
        _validatonDictionary = validationDictionary;
        _repository = repository;
    }

2 个答案:

答案 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)

如果它属于该服务的目的或域,您肯定可以让一个存储库/服务层处理多个实体。通常在简单的示例中 - 您是正确的,您没有看到这一点,但没有理由可以包含其他实体。

现在关于您的审计,为什么不调用您的审计服务层而不是包括审计对象(如果那就是您的意思)