【问题标题】:Get total row count in Entity Framework获取实体框架中的总行数
【发布时间】:2013-08-31 16:34:31
【问题描述】:

我正在使用实体框架来获取表的总行数。我只想要行数,没有 where 子句或类似的东西。以下查询有效,但速度很慢。返回 4475 的计数大约需要 7 秒。

我的猜测是它正在遍历整个表,就像IEnumerable.Count() 扩展方法的工作原理一样。

有没有办法“快速”获得总行数?有没有更好的办法?

    public int GetLogCount()
    {
        using (var context = new my_db_entities(connection_string))
        {
            return context.Logs.Count();
        }
    }

【问题讨论】:

  • 如何在不加载内容的情况下计算 EntityFramework 中的行? stackoverflow.com/questions/890381/…
  • 确保 context.Logs 是 DbSet、IDbSet 或 IQueryable,而不是 IEnumerable。如果它是一个 IEnumerable,则将获取并计算整个表。如果是 IQueryable,将生成查询以计算数据库中的行数,例如“SELECT COUNT(*) FROM dbo.Logs”(如果是 IdbSet 或 DbSet,它将被视为 IQueryable )

标签: c# sql-server entity-framework


【解决方案1】:

这是使用实体框架获取行数的方法。您可能会在第二次以上的查询中看到更快的性能,因为第一次运行它时会产生初始化成本。 (它应该在这里生成一个Select Count() 查询,而不是遍历每一行)。

如果您对更快地获取表中的原始行数感兴趣,那么您可能想尝试使用迷你 ORM,例如 DapperOrmLite

您还应该确保正确定义您的表(至少,它有一个主键),因为不这样做也会影响计算表中行数的时间。

【讨论】:

    【解决方案2】:

    如果您有权这样做,查询 sys 表以提取此信息会更快。

    例如

    public Int64 GetLogCount()
    {
        var tableNameParam = new SqlParameter("TableName", "Logs");
        var schemaNameParam = new SqlParameter("SchemaName", "dbo");
        using (var context = new my_db_entities(connection_string))
        {
            var query = @"
                SELECT ISNULL([RowCount],0)
                FROM (
                    SELECT  SchemaName,
                            TableName, 
                            Sum(I.rowcnt) [RowCount]
                    FROM    sysindexes I 
                            JOIN sysobjects O (nolock) ON I.id = o.id AND o.type = 'U' 
                            JOIN (
                                SELECT  so.object_id, 
                                        ss.name as SchemaName,
                                        so.name as TableName
                                    FROM   sys.objects SO (nolock) 
                                        JOIN sys.schemas SS (nolock) ON ss.schema_id = so.schema_id
                            ) SN 
                                ON SN.object_id = o.id 
                    WHERE   I.indid IN ( 0, 1 )
                    AND     TableName = @TableName AND SchemaName = @SchemaName
                    GROUP BY 
                            SchemaName, TableName
                ) A
            ";
    
            return context.ExecuteStoreQuery<Int64>(query, tableNameParam, schemaNameParam).First();
        }
    }
    

    【讨论】:

    【解决方案3】:

    您甚至可以使用实体框架触发 Raw SQL 查询,如下所示:

    var sql = "SELECT COUNT(*) FROM dbo.Logs";
    var total = context.Database.SqlQuery<int>(sql).Single();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      相关资源
      最近更新 更多