带有存储库和 UnitOfWork 的 EF CodeFirst CTP5:System.InvalidOperationException(...不是...的一部分...当前上下文...)

发布于 2024-10-08 14:10:32 字数 2781 浏览 1 评论 0原文

我正在测试 EF CodeFirst CTP5 并尝试实现工作单元和存储库模式。但是,当我运行一个简单的测试时,我得到:

System.InvalidOperationException:实体类型 Log 不是当前上下文模型的一部分。

数据库 get 由 EF 创建,当我调用 时它会失败。添加() 似乎没有使用相同的上下文,但我不明白为什么?

希望有聪明人来救我!
预先感谢您抽出宝贵时间。

这是一些代码:

LogCabinContext

public class LogCabinContext : DbContext, IUnitOfWork
{
    public LogCabinContext() { }

    public LogCabinContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {

    }

    #region IUnitOfWork Members

    public void Save()
    {
        base.SaveChanges();
    }

    #endregion
}

BaseRepository

public class BaseRepository<T> : IBaseRepository<T> where T : EntityBase
{
    public LogCabinContext _unitOfWork;
    private DbSet<T> _dbSet;

    public BaseRepository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new NullReferenceException("UnitOfWork must not be null");

        _unitOfWork = unitOfWork as LogCabinContext;
        _dbSet = _unitOfWork.Set<T>();
    }

    #region IBaseRepository Members

    public T GetById(int id)
    {
        return _dbSet.SingleOrDefault(x => x.Id == id);
    }

    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }

    public void Delete(T entity)
    {
        _dbSet.Remove(entity);
    }

    public IEnumerable<T> List()
    {
        return _dbSet.OrderBy(x => x.Id).AsEnumerable();
    }

    public IUnitOfWork CurrentUnitOfWork
    {
        get { return _unitOfWork; }
    }
    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        _unitOfWork.Dispose();
    }

    #endregion
}

SimpleTest,使用 Ninject 构建上下文,这是因为我创建了 DB

[TestFixture]
public class LogRepositoryTests
{
    IKernel _kernel;

    [SetUp]
    public void SetUp()
    {
        _kernel = new StandardKernel(new DatabaseModule());
    }

    [TearDown]
    public void TearDown()
    {
        _kernel.Dispose();
    }

   public ILogRepository GetLogRepository()
   {
        ILogRepository logRepo = _kernel.Get<ILogRepository>();

        return logRepo;
   }

   [Test]
   public void Test()
   {
        using (ILogRepository repo = this.GetLogRepository())
        {
           Log myLog = new Log();
           myLog.Application = "Test";
           myLog.Date = DateTime.Now;
           myLog.Exception = "Exception message";
           myLog.Machinename = "local";
           myLog.Message = "Testing";
           myLog.Stacktrace = "Stacktrace";

           repo.Add(myLog);
        }
   }
}

ILogRepository,所以现在只是从基础派生

public interface ILogRepository : IBaseRepository<Log>
{
}

I'm testing the EF CodeFirst CTP5 and was trying to implement The Unit Of Work and Repository patterns. But when I run a simple test I get:

System.InvalidOperationException : The entity type Log is not part of the model for the current context.

The Database get's created by the EF and it fails when I call .Add()
It seems that the same context is not being used but I can't figure out why?

Hoping for some smart human coming to rescue me!
Thanks in advance for taking your time.

Here is some code:

LogCabinContext

public class LogCabinContext : DbContext, IUnitOfWork
{
    public LogCabinContext() { }

    public LogCabinContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {

    }

    #region IUnitOfWork Members

    public void Save()
    {
        base.SaveChanges();
    }

    #endregion
}

BaseRepository

public class BaseRepository<T> : IBaseRepository<T> where T : EntityBase
{
    public LogCabinContext _unitOfWork;
    private DbSet<T> _dbSet;

    public BaseRepository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new NullReferenceException("UnitOfWork must not be null");

        _unitOfWork = unitOfWork as LogCabinContext;
        _dbSet = _unitOfWork.Set<T>();
    }

    #region IBaseRepository Members

    public T GetById(int id)
    {
        return _dbSet.SingleOrDefault(x => x.Id == id);
    }

    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }

    public void Delete(T entity)
    {
        _dbSet.Remove(entity);
    }

    public IEnumerable<T> List()
    {
        return _dbSet.OrderBy(x => x.Id).AsEnumerable();
    }

    public IUnitOfWork CurrentUnitOfWork
    {
        get { return _unitOfWork; }
    }
    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        _unitOfWork.Dispose();
    }

    #endregion
}

SimpleTest, using Ninject to build the context, this works since I creates the DB

[TestFixture]
public class LogRepositoryTests
{
    IKernel _kernel;

    [SetUp]
    public void SetUp()
    {
        _kernel = new StandardKernel(new DatabaseModule());
    }

    [TearDown]
    public void TearDown()
    {
        _kernel.Dispose();
    }

   public ILogRepository GetLogRepository()
   {
        ILogRepository logRepo = _kernel.Get<ILogRepository>();

        return logRepo;
   }

   [Test]
   public void Test()
   {
        using (ILogRepository repo = this.GetLogRepository())
        {
           Log myLog = new Log();
           myLog.Application = "Test";
           myLog.Date = DateTime.Now;
           myLog.Exception = "Exception message";
           myLog.Machinename = "local";
           myLog.Message = "Testing";
           myLog.Stacktrace = "Stacktrace";

           repo.Add(myLog);
        }
   }
}

ILogRepository, just derives from base for now

public interface ILogRepository : IBaseRepository<Log>
{
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文