有这个代码:
public class CategoriesController : Controller
{
private readonly WarhammerContext _context;
public CategoriesController(WarhammerContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
public IActionResult ProductListing()
{
var listingContext = _context.Product.Include(p => p.ProductFraction).Include(p => p.ProductType);
Dictionary<int, string> productImages = GetImagesByIds(listingContext.Select(p => p.Id));
foreach(var productId in productImages.Keys)
{
listingContext.Where(p => p.Id == productId).FirstOrDefault().ImageSource = productImages[productId];
}
ProductsViewModel pvm = new ProductsViewModel { ImageSources = productImages, Products = listingContext };
return View(pvm);
}
public Dictionary<int, string> GetImagesByIds(IEnumerable<int> productIds) =>
_context.ProductImage.Where(p => productIds.Contains(p.Id)).ToDictionary(key => key.ProductId, value => value.ImageSource);
}
引发此异常:“在前一个操作完成之前,在此上下文上启动了第二个操作。不保证任何实例成员都是线程安全的。”
试图这样做:
{
using (var context = new WarhammerContext())
{
return context.ProductImage.Where(p => productIds.Contains(p.Id)).ToDictionary(key => key.ProductId, value => value.ImageSource);
}
}
但随后在 ProductListing 中,productImages 字典变为空。它在调试器中给出错误,因为它已被释放。如何解决问题?
我也尝试制作 AddTransient,但它也没有帮助
EntityFramework 本身有一个惰性评估模型,只在需要时返回真实数据。在您的情况下,您正在查询以获取第一个数据,但实际上尚未获取数据本身。这只是准备。
然后将第一个请求传递给形成第二个请求的函数。结果,由于惰性模型,您有两个尚未请求其数据的请求。第二个请求开始提取真实数据,碰到第一个请求并运行它。结果,您得到两个同时执行的请求,并且 EntityFramework 出现错误。
在编译查询时,应该考虑惰性求值的这一特性。您可以通过编写强制 ToList() 来解决问题,然后将立即收到数据。