【发布时间】:2015-08-16 11:11:40
【问题描述】:
我想在实体框架和我的应用程序的其余部分之间创建一个抽象层。但是我在使用 Entity Framework 时遇到了一些问题。
基本上(我也没有向您展示我创建的所有接口层),我已经将我的应用程序拆分为多个项目,如下所示:
- 域
- 包含我的域对象,我的数据存储对象的抽象
- DAL
- 在我的数据存储和我的业务层之间创建一个链接。包含两种类型的元素:
- 私有对象:我的 EDMX、我的数据库对象和其他一些生成的对象,这些对象为我提供了一些有用的方法,例如 ToDomain/ToEntity
- 公共对象:我的数据访问对象,提供 CRUD 方法
- 在我的数据存储和我的业务层之间创建一个链接。包含两种类型的元素:
- 业务
- 包含我的应用程序的逻辑。只知道 DAL 和域层的公共元素。
- 演示文稿
- 为用户呈现域对象。只知道业务层。
正如我所说,我想创建我的数据存储对象的抽象(在我的情况下为 Database 对象,但我想要一个也适用于文件或 WCF 存储的解决方案),以便我的业务层不对我的 DAL 实施一无所知。
这是我在 DAL 中所做的一瞥:
public abstract class GenericDao<TEntity, TDomain, TDbContext> : IGenericDao<TDomain>
where TDbContext : DbContext, new()
where TEntity : class
where TDomain : class
{
protected TDbContext _context;
protected DbSet<TEntity> _dbSet;
public GenericDao(TDbContext dbContext)
{
this._context = dbContext;
this._dbSet = dbContext.Set<TEntity>();
}
public TDomain Create()
{
return this.ToDomain(this._dbSet.Create());
}
public IList<TDomain> GetAll()
{
return this._dbSet.ToList().Select(entity => this.ToDomain(entity)).ToList();
}
public void Update(TDomain domain)
{
var entity = this.ToEntity(domain);
var entry = this._context.Entry(entity);
entry.State = EntityState.Modified;
}
public void Remove(TDomain domain)
{
_dbSet.Remove(this.ToEntity(domain));
}
protected abstract TDomain ToDomain(TEntity entity);
protected abstract TEntity ToEntity(TDomain domain);
}
通过阅读我的代码,您可能会发现它有什么问题:当我尝试删除或更新实体时,我并没有在操作附加到 Entity Framework 的实体。如果我尝试将我的实体附加到dbContext,它会失败,因为上下文中已经有一个具有相同 ID 的实体。
我已经考虑过几种解决方案,但没有一个能让我满意。
也许我的方法有问题?我对 Repository 和 DAO 模式有点困惑(我在互联网上阅读了任何内容,但完全相反)。
【问题讨论】:
-
因为上下文中已经存在具有相同 id 的实体 - 为什么?
-
首先我检索一个实体。它存储在 dbContext 中。然后我将该实体作为新的域对象返回到我的业务层(因为我不希望我的业务层知道我的数据访问层的任何信息)。我的业务层执行其工作,然后在我的实体上调用更新。由于更新方法的入口点是我的域对象,因此我没有任何指向实体对象的指针。创建一个新的会导致我遇到的问题。使用 Kirill Bestemyanov 的第二个选项,我可以解决它,但我对它并不完全满意。我还在努力。我会告诉你的!
标签: c# entity-framework entity-framework-6