EF两次击中数据库..我做错了什么?

时间:2014-08-19 13:38:45

标签: c# entity-framework

我有以下代码:

    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();它命中数据库查找产品,但我认为它会使用我的产品列表&lt;&gt; ..任何人都可以说明为什么我的初始scrape =新的Scrape()没有将产品列表缓存到产品对象?

3 个答案:

答案 0 :(得分:3)

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

此外products.First(x => x.Asin == asin)products.First()完全不同,因此您没有缓存,但是它可以访问数据库两次的可用对象

答案 1 :(得分:0)

您的商品列表属于IEnumerable()

它命中getProducts上的数据库,因为这是它真正需要数据的唯一时间。

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

答案 2 :(得分:0)

问题是上下文实例上的属性 Products 正在实现IEnumerable,因此当您将它与您的字段产品关联时只是将可队容对象强制转换为IEnumerable。

如果您直接使用context.Products(请尝试),您将继续看到IEnumerable提供的First和可能的任何其他扩展方法。

因此,您需要将其强制转换为List以强制它在ctor上执行查询(与您为 ProxyServers 执行的操作相同)。

更多:

  1. 你正在做一个没有默认的第一个,它可能会抛出异常。
  2. 我不确定您为什么要验证产品上的第一个产品是否有ProductID&gt; 0.