使用Contains()优化实体框架查询的方法有哪些?

时间:2012-11-01 19:56:48

标签: entity-framework

从数据库加载大对象图。 该查询有许多Includes和Where()使用Contains()来过滤最终结果。 包含约一千个条目的集合调用包含。

分析器显示了人类难以理解的可怕SQL。 由于Contains(),无法预编译查询。

有没有办法优化此类查询?

更新

public List<Vulner> GetVulnersBySecurityObjectIds(int[] softwareIds, int[] productIds)
        {
            var sw = new Stopwatch();

            var query = from vulner in _businessModel.DataModel.VulnerSet
                        join vt in _businessModel.DataModel.ObjectVulnerTieSet.Where(ovt => softwareIds.Contains(ovt.SecurityObjectId))
                        on vulner.Id equals vt.VulnerId
                        select vulner;

            var result = ((ObjectQuery<Vulner>)query.OrderBy(v => v.Id).Distinct())
                .Include("Descriptions")
                .Include("Data")
                .Include("VulnerStatuses")
                .Include("GlobalIdentifiers")
                .Include("ObjectVulnerTies")
                .Include("Object.ProductObjectTies.Product")
                .Include("VulnerComment");

            //Если переданы конкретные продукты, добавляем фильтрацию
            if (productIds.HasValues())
                result = (ObjectQuery<Vulner>)result.Where(v => v.Object.ProductObjectTies.Any(p => productIds.Contains(p.ProductId)));

            sw.Start();
            var str = result.ToTraceString();
            sw.Stop();
            Debug.WriteLine("Сборка запроса заняла {0} секунд.", sw.Elapsed.TotalSeconds);
            sw.Restart();
            var list = result.ToList();
            sw.Stop();
            Debug.WriteLine("Получение уязвимостей заняло {0} секунд.", sw.Elapsed.TotalSeconds);

            return list;
        }

1 个答案:

答案 0 :(得分:2)

几乎可以肯定的是,尽管有更多的数据包往返,但将查询分割成碎片的效果更好。始终建议限制包含的数量,因为它们不仅会破坏查询的大小和复杂性(如您所注意到的),而且还会在长度和宽度上炸毁结果集。而且,它们经常被翻译成外连接。

除此之外,使用Contains的方式就行了。

抱歉,如果不了解您的数据模型和所涉及的表的大小,很难更具体。