2013-07-09 31 views
1

我有我的数据库上下文:ASP.NET MVC 3数据库上下文查询

public class ProductContext : DbContext 
{ 
    public ProductContext() : base ("DefaultConnection") {} 

    public DbSet<Product> Products {get;set;} 
} 

和我的仓库:

public class ProductRepository : IProductRepository 
{ 
    private ProductContext _dbContext = new ProductContext(); 

    public IQueryable<Product> Products { get { return _dbContext.Products; } } 
} 

当我查询我的EditAction数据库:

public ActionResult Edit(Guid id) 
{ 
    var item = _repository.Products.FirstOrDefault(x => x.Id.Equals(id)); 

    return View(item); 
} 

我通常会用一个ViewModel但这纯粹是为了展示场景。

当我使用var item行查询数据库时,EntityFramework是否更改item的状态。

我可以传递item各地通过ServicesService Layer众多,最后用我的方法保存:

public void SaveEntity<TEntity>(TEntity entityToSave) where TEntity : DbEntity 
{ 
    if (entityToSave.Id.Equals(Guid.Empty)) 
     _dbContext.Set<TEntity>().Add(entityToSave); 
    else 
     _dbContext.Entry<TEntity>(entityToSave).State = EntityState.Modified; 

    _dbContext.SaveChanges(); 
} 

它不会抛出一个异常说,已经有一个Entity与与您试图保存的那个相同Id

回答

1

所以,经过反复试验,似乎这工作完全正常,并且它不带回任何错误。有一件事看出来:

此导航属性:

public virtual Category Category { get;set; } 
public Guid CategoryId { get;set; } 

可以驻留在Product模型有一点点疑难杂症,那就是:

当编辑或保存新Product,你应该只设置CategoryId而不仅仅是Category完全因为你会得到复制Category个条目每次编辑或保存,如果您使用的是已经存在的数据库中的一个Category时间...

我想你应该在导航属性仅供您方便,不使用修改实体时...

+0

EF将尝试再次插入该类别,因为它很可能会附加到您的'DbContext'的另一个实例。 EF无法知道该类别已存在,所以它会尝试插入它,从而导致重复的键错误。这个问题可以通过在整个请求中使用'DbContext'的相同实例来解决。如上所述填写外键字段将工作得很好。 –

+0

是的,我认为这是问题,但我注入这将使用'DbContext'的一个实例库,我走动的地方实体,所以它只是更容易使用'Id'领域。 –

+0

确保您为请求的范围创建实例。 –