c#数据对象意外更新

时间:2014-08-06 20:54:30

标签: c# unity-container repository-pattern

我们遇到的问题是从存储库中获取数据,并在业务层中进行操作,这些更新无意中保存回数据库。

我们一直在假设数据库上下文已断开连接,并且只在我们调用特定保存方法时才更新数据。

我们的存储库类如下所示:

  public class OdsRepository : IOdsRepository, IDisposable
{
    public OdsContext DbContext { get; set; }

    public List<QueueErrorItem> GetQueueErrorItems<T>()
    {
        Type t = typeof(T);
        var ret = DbContext.QueueErrorItems.Where(p => p.DataType == t.Name).ToList();
        return ret;
    }

    public OdsRepository()
    {
        DbContext = new OdsContext();
    }

    public ApiKey CreateApiKey(ApiKey apiKey)
    {
        var ret = DbContext.ApiKeys.Add(apiKey);
        return ret;
    }

我认为我们不应该在默认构造函数中实例化上下文,我们使用的是Unity IOC,所以我认为这可能与问题有关。

基本上发生的事情是我们将从业务对象中调用一个reopsitory方法来获取一些数据,然后如果该数据被进一步操作以在另一个方法中使用,则该更改可能会无意中更新回到数据库中。

任何人都可以帮助诊断存储库代码更改或统一更改,这会使数据对象真正断开连接吗?

1 个答案:

答案 0 :(得分:1)

这是Entity Framework的默认行为。一旦执行.SaveChanges(),您将从上下文返回的实体所做的任何更改都将被保存。我的团队有一个类似的场景,我们需要在对象模型中构建临时数据以用于显示目的。我们最终将AsNoTracking()用于我们仅查看数据。此方法删除实体框架挂钩并防止无意中的数据库更新。

快速示例:

    public class Provider<TEntity> where TEntity : class
    {
        protected IObjectSet<TEntity> _dbSet;
        protected ObjectContext _context;

        public Provider(ObjectContext context)
        {
            _context = context;
            _dbSet = context.CreateObjectSet<TEntity>();
        }

        public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause= null)
        {
            IQueryable<TEntity> dbSet = _dbSet;

            if (whereClause!= null) 
                dbSet = dbSet.AsExpandable().Where(whereClause);

            return dbSet;
        }

        public virtual IEnumerable<TEntity> FindReadOnly(Expression<Func<TEntity, bool>> whereClause= null)
        {
            IQueryable<TEntity> dbSet = _dbSet.AsNoTracking();

            if (whereClause!= null) 
                dbSet = dbSet.AsExpandable().Where(whereClause);

            return dbSet;
        }
    }

请注意,简单的Find方法将允许您在保持实体框架更改跟踪器启用的同时收集实体。而ReadOnly对应物只是简单地将ChangeTracker与返回的实体分离。