我有一张表,列出了设备(我们将其详细信息存储在数据库中的硬件设备)的所有错误和警告。这由单个DeviceLog覆盖。

DeviceLog表存储当前错误和存档错误,这意味着尽管对于存档较大的设备来说,获取当前错误/警告状态非常慢。

device.Errors = databaseDevice.Errors.Where(
    e => e.Current &&
    e.LogEntryType == Models.DeviceLogEntryType.Error)
        .Select(e => new DeviceErrorLog()).ToList();


因此,在当前情况下,此特定设备的DeviceLog中大约有5000个条目,但device.Errors.Count() == 0中没有当前条目,但是如果在智能方面,我将鼠标悬停在databaseDevice.Errors上,它将显示实际的完整计数。

是这种现象吗?如果是这样,那么我该如何加快速度,因为我认为这应该是一种快速的操作,尤其是当我指定一个非常直接且易于搜索的数据子集时

要澄清数据结构:

public class DeviceLogEntry
{
    public DeviceLogEntryType /* An Enum */ LogEntryType { get; set; }
    public bool Current { get; set; }
}

最佳答案

但是如果以智能感知,我将鼠标悬停在databaseDevice.Errors上,它将显示实际的完整计数


为什么不呢?如果您将鼠标悬停在databaseDevice.Errors上,则intellisense将尝试为您提供有关databaseDevice.Errors的有用信息,其中Count(通过调用select count(*) from errors产生)就是此类示例。

包含device.Errors约束而不是Where的是databaseDevice.Errors


  如果是这样,那我该如何加快速度,因为我认为这应该是一个快速的操作


传递select count(*)应该是一个快速的操作。但这也与您的代码无关,因为在这种情况下,您的代码不是由intellisense运行的代码。您的代码是:

databaseDevice.Errors.Where(
    e => e.Current &&
    e.LogEntryType == Models.DeviceLogEntryType.Error)
        .Select(e => new DeviceErrorLog()).ToList()


这将执行类似的内容:

select * from errors where e.current = 1 and e.LogType = 52


(或该枚举值对应的任何整数)。

然后从中建立一个清单。在与实际执行的代码不对应的情况下,智能感知做什么都没关系。

但是,您可以做两件事来提高性能:


检查数据库表上的索引,因为能够快速查找currentlogEntryType将影响基础SQL的执行速度。
删除ToList(),除非您将不止一次处理这些结果。如果您不止一次要处理它,那就太好了;将其存入内存,并根据需要反复打。如果您将不止一次处理它,或者如果您处理这些问题的方式将涉及进一步的Where,那么不要浪费时间构建列表,而只要您可以,就可以再次查询该列表。只是查询结果本身。

关于c# - 当只需要一个子集时, Entity Framework 会加载大型表的所有记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20970715/

10-12 22:36