【问题标题】:LINQ: query very slowLINQ:查询很慢
【发布时间】:2018-10-24 14:20:41
【问题描述】:

我有以下数据库结构(仅显示相关表): 我需要获取表“Propietario”中所有元素的列表,并且每个元素必须在“Clave”中包含所有相关元素的列表。具体来说,我需要“Clave”中的“CodigoClave”字段。

另外,我需要能够过滤任何字段的结果。

这是我目前想出的:

int pageSizeP = (pageSize == null || pageSize == 0 || pageSize > 15) ? 15 : (int)pageSize;
int pageNumberP = (pageNumber == null || pageNumber == 0) ? 1 : (int)pageNumber;

var propietariosCount = context.Propietarios.Count();
var propietariosQuery = context.Propietarios
                        .AsEnumerable()
                        .OrderBy(p => p.Nombre).ThenBy(p => p.Apellido1).ThenBy(p => p.Apellido2)
                        .Select(p => new
                        {
                            Id = p.Id,
                            Nombre = p.Nombre,
                            Apellido1 = p.Apellido1,
                            Apellido2 = p.Apellido2,
                            NIF = p.NIF,
                            Claves = string.Join(", ", context.PropietariosFincas
                                                        .Where(pf => pf.PropietarioId == p.Id)
                                                        .Join(context.Expedientes
                                                                .Include(e => e.Clave),
                                                                pf => pf.FincaId,
                                                                e => e.FincaId,
                                                                (pf, e) => (e.Clave.CodigoClave + ((e.Clave.Alias == null) ? "" : " - " + e.Clave.Alias))
                                                        ).Distinct().ToList())
                           // Getting an array of Claves would do; 
                           // I could turn it into a string in the JS app
                           // But it's just as slow
                        });

if (criteriosBusqueda != "")
{
    string[] aCriterios = criteriosBusqueda.Split(new string[] { "," }, StringSplitOptions.None);

    CompareOptions compareOptions = CompareOptions.IgnoreCase;
    if (aCriterios[0] != "")
        propietariosQuery = propietariosQuery
                        .Where(p => p.Nombre != null)
                        .Where(p => p.Nombre.Replace("/", "__").ContainsIgnoreAccents(aCriterios[0], compareOptions));

    if (aCriterios[1] != "")
        propietariosQuery = propietariosQuery
                        .Where(p => p.Apellido1 != null)
                        .Where(p => p.Apellido1.Replace("/", "__").ContainsIgnoreAccents(aCriterios[1], compareOptions));

    if (aCriterios[2] != "")
        propietariosQuery = propietariosQuery
                        .Where(p => p.Apellido2 != null)
                        .Where(p => p.Apellido2.Replace("/", "__").ContainsIgnoreAccents(aCriterios[2], compareOptions));

    if (aCriterios[3] != "")
        propietariosQuery = propietariosQuery
                        .Where(p => p.NIF != null)
                        .Where(p => p.NIF.Replace("/", "__").ToLower().Contains(aCriterios[3].ToLower()));

    if (aCriterios[4] != "")
        propietariosQuery = propietariosQuery
                        .Where(p => p.Claves != null)
                        .Where(p => p.Claves.Replace("/", "__").ToLower().Contains(aCriterios[4].ToLower()));

}
var propietariosList = propietariosQuery.Skip((pageNumberP - 1) * pageSizeP).Take(pageSizeP)
                        .ToList();
var datosPropietarios = new
{
    pageSize = pageSizeP,
    pageNumber = pageNumberP,
    recordsNumber = propietariosQuery.Count()
    titulares = propietariosList
};

return Ok(datosPropietarios);

它可以工作,但速度太慢(需要几分钟)。我设法通过使 recordsNumber = context.Propietarios.Count() 快速进行初始查询(第一页,未过滤),但这会在过滤时破坏分页。无论如何,如果我过滤或转到接近末尾的页面,它又真的很慢。

如何使查询更快? 我的猜测是查询几乎遍历所有表,所以我不知道是否有不涉及更改数据模型的解决方案。

【问题讨论】:

    标签: linq


    【解决方案1】:

    这是因为您正在调用AsEnumerable,您正在将所有数据从Propietarios 表中提取到内存中,并且您在调用该方法后执行的其余操作是使用 Linq to Objects 而不是 Linq to Entities 执行的,所以您的查询未翻译为 sql。尝试删除它

    看看这个post,如果你需要更多信息AsEnumerable如何与EF一起工作

    【讨论】:

    • 是的,这似乎是速度的问题。但是,它不适用于我的原始查询。我正在使用不同的版本(在获得“Claves”的部分),它也很慢。过滤部分也不起作用。但我想这是另一个问题的问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多