我使用下面的存储库模式。当我从类中获取此异常的实例时:
public interface IRepository<TEntity> : IDisposable where TEntity : class
{
IQueryable<TEntity> GetQuery();
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
TEntity Single(Expression<Func<TEntity, bool>> predicate);
TEntity First(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void Delete(TEntity entity);
void Attach(TEntity entity);
void SaveChanges();
void SaveChanges(SaveOptions options);
}
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
private ObjectContext _context;
private IObjectSet<TEntity> _objectSet;
public GenericRepository(ObjectContext context)
{
_context = context;
_objectSet = _context.CreateObjectSet<TEntity>();
}
public IQueryable<TEntity> GetQuery()
{
return _objectSet;
}
public IEnumerable<TEntity> GetAll()
{
return GetQuery().AsEnumerable();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _objectSet.Where<TEntity>(predicate);
}
public TEntity Single(Expression<Func<TEntity, bool>> predicate)
{
return _objectSet.Single<TEntity>(predicate);
}
public TEntity First(Expression<Func<TEntity, bool>> predicate)
{
return _objectSet.First<TEntity>(predicate);
}
public void Delete(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_objectSet.DeleteObject(entity);
}
public void Add(TEntity entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
_objectSet.AddObject(entity);
}
public void Attach(TEntity entity)
{
_objectSet.Attach(entity);
}
public void SaveChanges()
{
_context.SaveChanges();
}
public void SaveChanges(SaveOptions options)
{
_context.SaveChanges(options);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && _context != null)
{
_context.Dispose();
_context = null;
}
}
}
使用:
var db = new AdventureWorks2012Entities();
IRepository<Person> person = new GenericRepository<Person>();
异常:
答案 0 :(得分:2)
问题是您使用的是Entity Framework 4.1或更高版本,DbContext
包裹ObjectContext
ObjectContext
。但是您的存储库仍然使用DbContext
。添加另一个构造函数,该构造函数接受public GenericRepository(DbContext context)
{
_context = (context as IObjectContextAdapter).ObjectContext;
_objectSet = _context.CreateObjectSet<TEntity>();
}
:
ObjectContext
您可以通过将DbContext
转换为IObjectContextAdapter
接口来检索已压缩的DbContext
实例。另一个选择是更新您的存储库类以使用最新的public class GenericRepository<TEntity> : IRepository<TEntity>
where TEntity : class
{
private DbContext _context; // instead of ObjectContext
private DbSet<TEntity> _set; // instead of IObjectSet<TEntity>
public GenericRepository(DbContext context)
{
_context = context;
_set = _context.Set<TEntity>();
}
public IQueryable<TEntity> GetQuery()
{
return _set;
}
public IEnumerable<TEntity> GetAll()
{
return GetQuery().AsEnumerable();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _set.Where<TEntity>(predicate);
}
// etc
}
,但这需要更多的编码,而不是简单地添加一个构造函数:
{{1}}
答案 1 :(得分:0)
这一切都在错误消息中,第一个很简单 - 您的存储库需要一个ObjectContext
参数(您没有提供)。
第二个基本上是说你的db
实例不属于ObjectContext
类型,或者至少不能向下转换为该特定类型。如果您的确定 AdventureWorks2012Entities
来自ObjectContext
,那么您可以进行直播,例如。
IRepository<Person> repo = new GenericRepository<Person>((ObjectContext)db);
答案 2 :(得分:0)
您可以将DbSet传递到存储库,所以:
var db = new AdventureWorks2012Entities();
IRepository<Person> person = new GenericRepository<Person>(db.Person);
在AdventureWorks2012Entities DbContext类中声明db.Person。
我正在开发一个UnitOfWork / Repository抽象层,以便轻松地从NHibernate / EntityFramework / Raven和其他人切换,并更好地允许测试。
Here源代码和here Nuget包。我要更改代码库以更好地支持DDD方法,特别是: