我一直在使用以下T-SQL来获取数据库中表的已用空间(以兆字节为单位):
SELECT
t.NAME AS TableName,
CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN
sys.schemas s ON t.schema_id = s.schema_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
GROUP BY
t.Name, s.Name, p.Rows
ORDER BY
t.Name
结果如下:
是否有使用EF Core执行等效操作的好方法?
我浏览了Raw SQL Queries文档,但是那里的示例似乎并不适用,因为它们主要与检索实体有关。
答案 0 :(得分:1)
您可以同时使用QueryTypes和Raw SQL Queries。
首先,创建一个代表您的结果并封装SQL查询的类。您可以根据需要组织以下代码,但这应该可以使您理解。
public class DatabaseTableSize
{
public class View
{
public string TableName { get; private set; }
public decimal TableSizeMb { get; private set; }
}
public static async Task<List<View>> Query(YourDbContextType dbContext)
{
return await dbContext.DatabaseTableSizeView
.FromSql(@"SELECT
t.NAME AS TableName,
CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TableSizeMb
FROM sys.tables t
INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
GROUP BY
t.Name, s.Name, p.Rows
ORDER BY
t.Name")
.ToListAsync();
}
}
然后将QueryType定义添加到您的DbContext
public DbQuery<DatabaseTableSize.View> DatabaseTableSizeView { get; set; }
然后在任何需要数据的地方调用它
var results = await DatabaseTableSize.Query(dbContext);
答案 1 :(得分:1)
我们绝对可以使用Raw SQL查询来完成这项工作。
首先,当我们运行此查询时,最好以实体框架可以使用的类类型返回结果。我曾尝试检索任意查询结果,但发现这些结果很难解析。 我的建议是创建一个类来描述您将从RawSQL查询中获得的结果。
因此,无论您在哪里为该项目存储模型(甚至在新文件中),我们都将创建一个名为SpaceCalculations
的新类,并使用[NotMapped]
属性对其进行修饰,以防止EF Core试图将其制成表格。
[NotMapped]
public class SpaceCalculations
{
public string TableName { get; set; }
public decimal TotalSpaceMB { get; set; }
}
接下来,我们需要在我们的DBContext中注册该类。在您的DBContext中定义各种Dbset<Type>
记录的位置,添加以下内容:
public DbQuery<SpaceCalculations> SpaceCalculations { get; set; }
最后,要检索数据本身,只需将其懒惰地放入Home \ Index控制器动作中即可。
public IActionResult Index()
{
List<SpaceCalculations> SpaceData = _context.SpaceCalculations.
FromSql(@"YOUR LONG SQL STATEMENT HERE").ToList();
ViewBag.SpaceInfo = SpaceData;
return View();
}
然后,为了渲染信息,我在Index.cshtml
文件中创建了以下内容。
<h2>Table Space for table ....</h2>
<table>
<tr>
<th>
TableName
</th>
<th>
TableSpace
</th>
</tr>
@foreach (SpaceCalculations SpaceRecord in ViewBag.SpaceInfo)
{
<tr>
<td>
@SpaceRecord.TableName
</td>
<td>
@SpaceRecord.TotalSpaceMB
</td>
</tr>
}
</table>
还有完成的结果!