LINQ抱怨在服务实现多个存储库时使用了不同的EF上下文

本文关键字:上下文 EF 服务 实现 存储 LINQ | 更新日期: 2023-09-27 18:18:09

我有一个我的存储库继承的BaseRepository。代码声明如下:

public interface IBaseRepository<T> : where T : class 
{
    IQueryable<T> GetAll();
}
public abstract class BaseRepository<C, T> : IBaseRepository<T>
    where T : class
    where C : DbContext, new()
{
    protected BaseRepository()
    {
        _context = new C();
        _context.Database.Log = message => Trace.WriteLine(message);
    }
    private readonly C _context;
    protected C Context
    {
        get { return _context; }
    }
    public virtual IQueryable<T> GetAll()
    {
        return _context.Set<T>();
    }
}
public interface IARepository : IBaseRepository<A>
{
}
public ARepository : BaseRepository<Entities, A>, IARepository
{
}
public interface IBRepository : IBaseRepository<B>
{
}
public ARepository : BaseRepository<Entities, B>, IBRepository
{
}

然后我有一个服务层,它将使用多个存储库为我的控制器获取数据。

public class SomeService 
{
    private readonly IARepository _aRepository;
    private readonly IBRepository _bRepository;
    public EventService(IARepository aRepository, IBRepository bRepository)
    {
        _aRepository = aRepository;
        _bRepository = bRepository;
    }
    public EventService() : this(new ARepository(), new BRepository())
    {
    }
    public IEnumerable<SomeDTO> GetSomeDTOs()
    {
        return _aRepository.GetAll()
            .Join(_bRepository.GetAll(), a => a.SomeId, b => b.SomeId, (c, d) => new SomeDTO
                {
                    ...
                    ...
                    ...
                }).ToList();
    }
}

但问题来了。我得到以下错误:

类型为'System '的第一次异常。NotSupportedException"由于发生在EntityFramework.SqlServer.dll

附加信息:指定的LINQ表达式包含引用与不同上下文相关联的查询。

当我调用GetSomeDTOs函数。从我所看到的,它应该使用与在基础存储库中声明的相同的上下文。这里有什么问题吗?

LINQ抱怨在服务实现多个存储库时使用了不同的EF上下文

问题是每个存储库都有自己的上下文,因此您不能将它们连接在一起。一个简单的修复方法是创建一个共享上下文并将其传递到您的存储库:

public abstract class BaseRepository<C, T> : IBaseRepository<T>
    where T : class
    where C : DbContext
{
    protected BaseRepository(C context)
    {
        _context = context;
        _context.Database.Log = message => Trace.WriteLine(message);
    }
    //snip
}

并像这样创建您的存储库:

var context = new MyDbContext();
IARepository aRepository = new ARepository(context);
IBRepository bRepository = new BRepository(context);