EF 6中的此TestDBSet类是否可以修改为与EF Core配合使用?

时间:2019-02-18 15:36:48

标签: c# dependency-injection .net-core mocking entity-framework-core

我正在尝试按照EF 6的本教程编写用于模拟测试Entity Framework核心的自己的双打测试:

https://docs.microsoft.com/en-us/ef/ef6/fundamentals/testing/writing-test-doubles

本教程卡在TestDbSet类上,该类应提供DbSet的内存实现。但是,大多数成员与EF Core不兼容:

public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity>
    where TEntity : class
{
    ObservableCollection<TEntity> _data;
    IQueryable _query;

    public TestDbSet()
    {
        _data = new ObservableCollection<TEntity>();
        _query = _data.AsQueryable();
    }

    public override TEntity Add(TEntity item)
    {
        _data.Add(item);
        return item;
    }

    public override TEntity Remove(TEntity item)
    {
        _data.Remove(item);
        return item;
    }

    public override TEntity Attach(TEntity item)
    {
        _data.Add(item);
        return item;
    }

    public override TEntity Create()
    {
        return Activator.CreateInstance<TEntity>();
    }

    public override TDerivedEntity Create<TDerivedEntity>()
    {
        return Activator.CreateInstance<TDerivedEntity>();
    }

    public override ObservableCollection<TEntity> Local
    {
        get { return _data; }
    }

    Type IQueryable.ElementType
    {
        get { return _query.ElementType; }
    }

    Expression IQueryable.Expression
    {
        get { return _query.Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return new TestDbAsyncQueryProvider<TEntity>(_query.Provider); }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
    {
        return new TestDbAsyncEnumerator<TEntity>(_data.GetEnumerator());
    }
}

Add,Attach,Remove和Create方法的所有四个错误均相同:

  

'TestDbSet .Add(TEntity)':返回类型必须为   'EntityEntry '以匹配重写的成员   'DbSet .Add(TEntity)

有人可以解释我是否可以将转换为EntityEntry ,或者是否有更好的方法来解决此问题?非常感谢

2 个答案:

答案 0 :(得分:1)

对于EntityEntry<TEntity>,它指示跟踪的TEntity并检查源代码,它使用StateManager来将TEntity转换为EntityEntry<TEntity>

您无法在StateManager中创建TestDbSet<TEntity>

尝试检查以下代码是否适合您。

public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>
    where TEntity : class
{
    ObservableCollection<TEntity> _data;
    IQueryable _query;

    public TestDbSet()
    {
        _data = new ObservableCollection<TEntity>();
        _query = _data.AsQueryable();
    }

    public override EntityEntry<TEntity> Add(TEntity item)
    {
        _data.Add(item);
        var entity = base.Attach(item);
        return entity;
    }
}

答案 1 :(得分:0)

@Edward您的解决方案非常出色,通过返回null,至少在我的测试中,该教程现在与EF core兼容,谢谢您的提示。

TestContext中的一些修改: -使用Microsoft.EntityFrameworkCore.Query.Internal; -使用Microsoft.EntityFrameworkCore.ChangeTracking; -将IDbAsyncEnumaerable和IDbAsyncEnumerator更改为IAsyncEnumerable和IAsyncEnumerator -添加,删除和附加方法:将返回类型从TEntity更改为EntityEntry,并更改每个方法中的最后一条语句以返回null; -其他一些方法将显示编译错误,只需删除它们即可。