2015-09-26 52 views
2

我正在尝试应用this blog中所述的工作模式单元,但遇到了以下问题:如果仅将相关的DbSet注入回购,例如,仅使用DbSet更新对象

public ArticleRepository(DbSet<Article> articles) 
{ 
    this.articles = articles; 
} 

那么我该如何更新记录或将其状态设置为已修改?

之前我用

public void Update(Article article) 
{ 
    this.context.Entry(article).State = EntityState.Modified; 
} 

但随着新的方法,我没有访问的DbContext了。 DbSet.Add和DbSet.Attach都不能在这里工作,所以我如何更新上下文中的对象?

+1

'IGenericRepository'应完全由您的设计。您可以添加一些方法来为其中的实体设置状态。这种界面真的看起来像一个包装。所以如果可能的话,尝试通过其他一些隐藏的界面暴露核心部分(DbContext,...)。在需要时,您可以随时访问核心以执行一些***高级***任务。作为包装,有时它不能像核心部件那样提供完整的操作。对我而言,这种模式很大程度上取决于所谓的***包装***。 – Hopeless

+0

1.您可以从'DbSet'访问上下文。 2.不要注入'DbSet',注入上下文本身,然后使用上下文设置'this.articles'。 3.你知道你为什么抽象了背景吗?实体框架上下文已经具有内置的工作单元机制。 – haim770

回答

3

System.Data.Entity.Migrations.IDbSetExtensions包含IDbSet扩展AddOrUpdate <TEntity>。这将更新实体。

有些人喜欢不知道他们是添加一个新实体还是改变一个现有的好处。

但是,如果你真的想要一个错误,如果你要更新的没有添加的项目,看看在Source Code of IDbSetExtensions.AddOrUpdate

在这里你可以看到,如果函数首先检查的项目存在,并且根据结果添加或更新,如下所示:

var existing = set.SingleOrDefault 
    (Expression.Lambda<Func <TEntity, bool>> (matchExpression, new[] 
     {parameter})); 

if (existing != null) 
{ // entity exists: update it 
    foreach (var keyProperty in keyProperties) 
    { 
     keyProperty.Single().SetValue 
      (entity, keyProperty.Single().GetValue (existing, null), null); 
    } 
    internalSet.InternalContext.Owner.Entry(existing) 
     .CurrentValues.SetValues (entity); 
} 
else 
{ // not existing entity: Add it 
    internalSet.Add(entity); 
} 

如果你不想AddOrUpdate,但实际上只是一个更新,考虑为IDbSet自己的扩展方法。请参阅Extension Methods (C# Programming Guide)