0

我正在使用 EF 和 MVVM 模式。我的问题是关于数据访问层的。在 DAL 我有以下课程:

  1. MyObjectContext这在技术上是现在的标准 ObjectContext,但稍后将添加一些工作单元方法。

  2. Repository<TModel>它处理不同 ObjectSet 上最需要的查询(例如 Add、GetAll、...)。

  3. 其中一些DataServices利用存储库为 Core 提供更高级别的数据访问。

我正在处理的项目是一个业务应用程序,到目前为止大约有 100 个 EntitySet,有时用户的单个交互可能涉及多达 20 个不同的 EntitySet(更新其中的大多数)。我目前添加.Include(params string[])到我的查询中以防止ObjectContextDisposedException但它似乎不是一个可靠的解决方案。

问题是我应该在每个 DataService 方法中创建一个实例MyObjectContext(因此是存储库)(如以下代码,在我看来,在这种情况下工作单元的能力将毫无用处)还是应该在外部创建它DataService 并通过它们的构造函数(或直接传递给每个 DataService 方法)将其传递给 DataService,以一起处理一堆数据库操作(不同的表和查询)。如何?

如下MyObjectContext所示:

public class MyObjectContext : ObjectContext, IUnitOfWork
{
    public MyObjectContext()
        : base("name=EdmContainer", "EdmContainer")
    {
        ContextOptions.LazyLoadingEnabled = true;
    }

    #region IUnitOfWork Members
    public void Commit()
    {
        SaveChanges();
    }
    #endregion
}

这是Repository这样的:

public class Repository<TModel>
{
    private readonly SoheilEdmContext _context;

    public Repository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new ArgumentNullException("unitOfWork");

        _context = unitOfWork as SoheilEdmContext;
    }
    public TModel FirstOrDefault(Expression<Func<TModel, bool>> where)
    {
        return _context.CreateObjectSet<TModel>().FirstOrDefault(where);
    }
    public void Add(TModel entity)
    {
        _context.CreateObjectSet<TModel>().AddObject(entity);
    }
    ...
}

这就是常见的DataService样子:

public class JobDataService : IDataService<Job>
{
    #region IDataService<Job> Members
    public Job GetSingle(int id)
    {
        Job model = null;
        using (var context = new MyObjectContext())
        {
            var repos = new Repository<Job>(context);
            model = repos.FirstOrDefault(x => x.Id == id);
        }
        return model;
    }

    public IEnumerable<Job> GetAll()
    {
        using (var context = new MyObjectContext())
        {
            var repos = new Repository<Job>(context);
            var models = repos.GetAll();
            return models;
        }
    }

    public IEnumerable<Job> GetActives()
    {
        throw new NotImplementedException();
    }

    public int AddModel(Job model)
    {
        using (var context = new MyObjectContext())
        {
            var repos = new Repository<Job>(context);
            repos.Add(model);
            context.SaveChanges();
        }
    }

    public void UpdateModel(Job model)
    {
        throw new NotImplementedException();
    }

    public void DeleteModel(Job model)
    {
        using (var context = new MyObjectContext())
        {
            var repos = new Repository<Job>(context);
            var model = repos.FirstOrDefault(x => x.Id == model.Id);
            if (model == null) return;
            repos.Delete(model);
            context.SaveChanges();
        }
    }
    #endregion
}

任何想法或见解都会受到赞赏。

4

1 回答 1

1

您可以在每个服务中创建 MyObjectContext 的实例,例如 JobDataService,但是这会使您的代码变得混乱并且难以维护。在 DataService 之外创建 MyObjectContext 的实例更好。你现在所拥有的,如果你有 100 个 EntitySet,你必须创建 100 个 DataService。那是因为这里使用“Repository Pattern”和“UnitOfWork”效率不高。我建议执行以下操作:

对象上下文

public class MyObjectContext : ObjectContext
{
    public MyObjectContext() : base("name=EdmContainer", "EdmContainer")
    {
        ContextOptions.LazyLoadingEnabled = true;
    }

    #region IUnitOfWork Members
    public void Commit()
    {
        SaveChanges();
    }
    #endregion
}

通用存储库

 public interface IRepository<TModel> where TModel : class
    {
        void Add(TModel entity);
        IEnumerable<TModel> GetAll();
        // Do some more implement
    }


    public class Repository<TModel> : IRepository<TModel> where TModel : class
    {
        private readonly ObjectContext _context;

        public Repository(ObjectContext context)
        {
            _context = context;
        }

        public virtual void Add(TModel entity)
        {
            _context.CreateObjectSet<TModel>().AddObject(entity);
        }

        public virtual IEnumerable<TModel> GetAll()
        {
            return _context.CreateObjectSet<TModel>();
        }
    }

工作单位

public interface IUnitOfWork : IDisposable
{
    IRepository<Job> Jobs { get; }
    IRepository<User> Users { get;} 
    void Commit();
}

    public class UnitOfWork : IUnitOfWork
    {
        private readonly SoheilEdmContext _context;
        private readonly IRepository<Job> _jobRepository;
        private readonly IRepository<User> _userRepository; 

        public UnitOfWork(SoheilEdmContext context)
        {
            _context = context;
            _jobRepository = new Repository<Job>(_context);
            _userRepository = new Repository<User>(_context);
        }
        public IRepository<Job> Jobs{get { return _jobRepository; }}
        public IRepository<User> Users{get { return _userRepository; }}
        public void Commit(){_context.Commit();}
        public void Dispose()
        {
            if (_context != null)
            {
                _context.Dispose();
            }

            GC.SuppressFinalize(this);
        }

乔德数据服务

public interface IDataService
        {
            IEnumerable<Job> GetAll();
        }

        public class DataService : IDataService
        {
            private readonly IUnitOfWork _unitOfWork;
            public DataService(IUnitOfWork unitOfWork)
            {
                _unitOfWork = unitOfWork;
            }

            public IEnumerable<Job> GetAll()
            {
                return _unitOfWork.Jobs.GetAll();
            }
        }

这里我使用接口来实现一切,如果你想做同样的事情,你需要使用 IoC Container。我使用了“Simple Injector”,你可以在这里找到它:

简单的喷油器

还有一个建议,如果你觉得你有太多的 I/O 操作需要实现,比如数据库访问、查询数据等,你应该考虑使用异步。下面是一个关于异步的好视频。

如何使用异步构建 ASP.NET Web 应用程序

于 2013-11-02T20:08:37.600 回答