1

我使用以下存储库模式。当我从类中实例获取此异常时:

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

例外: 在此处输入图像描述

在此处输入图像描述

4

3 回答 3

2

问题是您使用的是 Entity Framework 4.1 或更高版本,它DbContextObjectContext. 但是您的存储库仍然使用ObjectContext. 添加另一个构造函数,它接受DbContext

public GenericRepository(DbContext context)
{
    _context = (context as IObjectContextAdapter).ObjectContext;
    _objectSet = _context.CreateObjectSet<TEntity>();
}

您可以通过转换为接口来检索包装ObjectContext的实例。另一种选择是更新您的存储库类以使用 latest ,但这将需要更多的编码,而不是简单地添加一个构造函数:DbContextIObjectContextAdapterDbContext

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
}
于 2013-02-11T12:19:05.260 回答
0

您可以将 DbSet 传递给您的存储库,因此:

var db = new AdventureWorks2012Entities();
IRepository<Person> person = new GenericRepository<Person>(db.Person);

其中 db.Person 在 AdventureWorks2012Entities DbContext 类中声明。

我正在开发一个 UnitOfWork/Repository 抽象层,以便轻松地从 NHibernate/EntityFramework/Raven 等切换并更好地允许测试。

这里是源代码,这里是 Nuget 包。我必须更改代码库以更好地支持DDD方法,特别是:

  1. 删除工作单元类,不需要,因为每次使用一个聚合
  2. 将 Commit 方法添加到存储库
于 2013-02-11T12:24:01.720 回答
0

这全部都在错误消息中,第一个很简单 - 您的存储库需要一个ObjectContext参数(您没有提供)。

第二个基本上是说您的db实例不是类型ObjectContext或至少不能向下转换为该特定类型。如果你确定 AdventureWorks2012Entities从那时ObjectContext你可以做一个直接的演员,例如

IRepository<Person> repo = new GenericRepository<Person>((ObjectContext)db);
于 2013-02-11T12:21:11.870 回答