【问题标题】:LINQ complains about different EF contexts used in Service implementing multiple repositoriesLINQ 抱怨在实现多个存储库的服务中使用了不同的 EF 上下文
【发布时间】:2015-10-16 18:09:52
【问题描述】:

我有一个 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 函数时。从我可以看到它应该使用与在基本存储库中声明的相同的上下文。这里似乎有什么问题?

【问题讨论】:

  • 啊,_aRepository_bRepository 有单独的上下文对象。如果你想一起Join他们,他们需要参考同一个。
  • 我是怎么做到的?存储库和服务位于没有 App.Start 的类库中,我通常会使用 Unity.RegisterComponents();
  • 哦,所以你确实有一个 IoC 容器。所以,你需要告诉它上下文是在它们之间共享的。

标签: c# entity-framework linq


【解决方案1】:

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

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

【讨论】:

  • 啊,这么简单。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 2013-03-09
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 2011-01-09
  • 2020-02-08
相关资源
最近更新 更多