在我的LabelService中,我正在尝试将OrderLineRepository中的记录与LabelRepository连接起来。当我这样做时,我收到此错误:
指定的LINQ表达式包含对查询的引用 与不同的背景相关联。
这个问题的最佳解决方案是什么?任何建议将不胜感激。
以下是我的两个存储库的代码:
public class LabelRepository : ILabelRepository
{
private OrderContext _context;
public LabelRepository(string connectionName)
{
_context = new OrderContext(connectionName);
}
public LabelRepository()
{
_context = new OrderContext();
}
public LabelRepository(OrderContext context)
{
_context = context;
}
}
public class OrderLineRepository : IOrderLineRepository
{
private OrderContext _context;
public OrderLineRepository(string connectionName)
{
_context = new OrderContext(connectionName);
}
public OrderLineRepository()
{
_context = new OrderContext();
}
public OrderLineRepository(OrderContext context)
{
_context = context;
}
}
以下是我的LabelService中的部分代码:
public class LabelService : ILabelService
{
private readonly ILabelRepository _labelRepository;
private readonly IOrderLineRepository _orderLineRepository;
public LabelService(ILabelRepository labelRepository, IOrderLineRepository orderLineRepository)
{
_labelRepository = labelRepository;
_orderLineRepository = orderLineRepository;
}
public List<Label> GetLabelsOrderedByCustomerId(string customerId)
{
var labels = (from ol in _orderLineRepository.GetAll()
join l in _labelRepository.GetAll() on new {ol.QualityId, ol.CustomerId, ol.SerialNumber} equals
new {l.QualityId, l.CustomerId, l.SerialNumber}
where ol.OrderCustomer == customerId
select l).Distinct().ToList();
return labels;
}
}
Unity用于依赖注入:
public class Resolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
if (serviceType == typeof (LabelsController)) {
return new LabelsController(
new LabelService(new LabelRepository(), new OrderLineRepository()),
new OrderLineService(new OrderLineRepository())
);
}
return null;
}
}
答案 0 :(得分:2)
当我需要在存储库之间共享上下文时,我倾向于引入一个重载的构造函数,它允许我传入一个上下文。最好将你的上下文包装在一个漂亮的界面中,例如。
public partial OrderContext : DbContext, IContext
{
...
}
public class OrderLineRepository : IOrderLineRepository
{
public OrderLineRepository(string connectionString)
: this(new OrderContext(connectionName))
{
}
public OrderLineRepository(IContext context)
{
this.Context = (OrderContext)context;
}
public IContext Context { get; private set; }
}
然后在你的解析器中你可以做到
public object GetService(Type serviceType)
{
if (serviceType == typeof (LabelsController)) {
var labelRepo = new LabelRepository();
var orderRepo = new OrderLineRepository(labelRepo.Context);
return new LabelsController(
new LabelService(labelRepo, orderRepo),
new OrderLineService(orderRepo)
);
}
return null;
}
或者,我过去使用的另一种方法是使用UnitOfWork
类型类来暴露上下文,例如。
public interface IUnitOfWork : IDisposable
{
public IContext Context { get; }
}
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork(string connectionString)
{
this.Context = new OrderContext(connectionString);
}
public IContext Context { get; private set; }
public void Dispose()
{
if (Context != null)
Context.Dispose();
}
}
在您的方案中,我会更新我的存储库以获得读/写Context
属性,这样您就可以在服务中交换它们
public List<Label> GetLabelsOrderedByCustomerId(string customerId)
{
using (var uow = new UnitOfWork(connectionString))
{
_labelRepository.Context = uow.Context;
_orderLineRepository.Context = uow.Context;
var labels = (from ol in _orderLineRepository.GetAll()
join l in _labelRepository.GetAll() on new {ol.QualityId, ol.CustomerId, ol.SerialNumber} equals
new {l.QualityId, l.CustomerId, l.SerialNumber}
where ol.OrderCustomer == customerId
select l).Distinct().ToList();
return labels;
}
}
答案 1 :(得分:-4)
最佳解决方案是完全停止使用存储库。 DbContext
能够很好地隐藏数据库,而且存储库并不能帮助您进行单元测试(您花了很多时间创建模拟版本,而您真正应该做的是为单元测试创建数据库实例并使用EF)。
除此之外,您应该将相同的上下文传递给所有存储库,这样您就可以非常轻松地在它们之间共享对象。