通用实体保存方法不起作用?

时间:2012-04-26 21:33:09

标签: c# asp.net-mvc-3 entity-framework

为了减少我使用的代码和类的数量,我得到了这个方法:

public TEntity Save(TEntity entity)
            {
                var validatationErrors = Entities.GetValidationErrors().ToList();
                if (validatationErrors.Count() > 0)
                    throw new ValidateException(validatationErrors);

                if (Entities.Entry(entity).State == EntityState.Added)
                    Entities.Set<TEntity>().Add(entity);
                else
                    Entities.Set<TEntity>().Attach(entity);

                Entities.SaveChanges();
                Entities.Entry(entity).Reload();
                return entity;
            }

当我创建新产品时,它会跳过将其添加到数据库的条件。因此没有得救。同样的,如果我尝试修改它不会改变的东西。

为了解决这个问题,我必须将我的实体保存在控制器中,如下所示:

using (var db = new EntitiesDbContext())
                {
                    db.Products.Attach(product);
                    db.Entry(product).State = EntityState.Modified;
                    db.SaveChanges();
                }

这看起来效率很低。 所以我真的想知道通用保存有什么问题让它无效?

2 个答案:

答案 0 :(得分:1)

  • 您的代码错了。在您的情况下,您不需要Attach您的实体。您只需要Add您的实体DbSet

            public TEntity Save(TEntity entity)
            {
                Entities.Set<TEntity>().Add(entity);        
                Entities.SaveChanges();
            }
    

你应该记住:

Entities.Set<TEntity>().Add(entity);

等于

db.Entry(entity).State = EntityState.Added;

entity.Property = newProperty;

将实体状态设置为Modifieddb.Entry(entity).StateEntityState.Modified

您无需验证和重新加载实体。 ObjectContext为你做。

  • 要条件化您的实体,请尝试以下操作:

        public TEntity Save(TEntity entity)
        {
    
            var dbEntity = Entities.Set<TEntity>().Find(entity.Id);
    
            if (dbEntity != null)               
                dbEntity = entity;
            else
                Entities.Set<TEntity>().Add(entity);
    
            Entities.SaveChanges();
        }
    

答案 1 :(得分:0)

如果您创建新实体,则应使用.Add方法。如果你有一个你知道它存在于数据库中的对象并且你想避免去数据库去获取它,那么应该使用.tatch。

通用Save方法似乎也存在一些问题:

  • 除非您明确禁用验证,否则您将多次验证实体,因为默认情况下.SaveChanges()将验证实体
  • 如果实体处于已添加状态,则它已被上下文跟踪,因此无需再次添加
  • .SaveChanges()将尝试保存未处于Unchanged状态的上下文跟踪的所有实体。该方法给人的印象是它只会保存你传递的实体,但实际上它可以节省更多
  • 我认为调用DbEntityEntry.Reload()只对附加实体有意义,用数据库中的值更新属性值 - 如果你这样做总是那么我想知道为什么你附加实体而不是从数据库中获取它。