EF访问数据库两次.我做错了什么?



我有以下代码:

    private static List<ProxyServer> proxyServers = new List<ProxyServer>();
    private static IEnumerable<Product> products = new List<Product>();
    private static CharonTestEntities3 context = new CharonTestEntities3();
    public Scrape()
    {
        proxyServers = context.ProxyServers.ToList();
        products = context.Products;
    }
    private ProxyServer getProxy(int countryID)
    {
        //TODO: random proxy based on last usage (< 40 seconds)
        return proxyServers.FirstOrDefault();

    }
    private bool getProducts(string asin)
    {
        var product = products.First(x => x.Asin == asin);
        if (products.First().ProductID > 0)
        {
            return true;
        }
        return false;
    }
    public void DoScrape(SearchCriteria criteria)
    {
        getProducts("A1234543345");
    }

当我运行getProducts();它会访问数据库查找产品,但我认为它会使用我的产品列表<>..谁能解释一下为什么我最初的刮=新刮()不缓存产品列表到产品对象?

因为代码products = context.Products;不是一个列表,而是一个可查询对象。如果您将代码更改为products = context.Products.ToList();,它将查询SQL的所有数据一次。

此外,products.First(x => x.Asin == asin)是完全不同的products.First(),所以你没有缓存,但可查询的对象,它击中数据库两次

您的产品列表类型为IEnumerable()

它在getProducts上访问DB,因为这是它真正需要数据的唯一时间。

要解决这个问题,在Scrape()中,将.ToList()添加到context.Products

问题在于context实例上的属性Products正在实现IEnumerable,因此当您将其关联到您的字段Products时,您只是将可查询对象转换为IEnumerable。

如果使用context,您将继续看到First以及IEnumerable提供给您的任何其他扩展方法。产品直接(请试用)。

因此,您需要将其强制转换为List以强制它对actor执行查询(与您对ProxyServers所做的相同)。

:

  1. 你正在做一个没有Default的First,它可能会抛出一个异常。
  2. 我不知道你为什么要验证产品上的第一个产品是否有ProductID> 0。

最新更新