0

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

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();
                }

这似乎相当低效。所以我想知道导致它不起作用的通用保存真的有什么问题?

4

2 回答 2

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;

将实体状态设置为Modified( db.Entry(entity).Stateis EntityState.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();
        }
    
于 2012-04-27T15:13:23.810 回答
0

如果你创建一个新实体,你应该使用 .Add 方法。如果您有一个知道它存在于数据库中的对象并且您希望避免访问数据库来获取它,则应该使用 .Attach。

通用的 Save 方法似乎也有一些问题:

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