簡體   English   中英

EF Core自定義計數查詢

[英]EF Core custom count query

我正在研究一個小型ASP.NET Core項目,該項目用於在Sqlite數據庫上使用Entity Framework Core標記圖像。 有兩個表(和POCO),標簽和圖像,其中每個標簽與多個標簽相關。 我正在嘗試對所有具有與之關聯的標簽的圖像進行計數。

在普通的SQL中,我SELECT COUNT(DISTINCT ImageId) FROM Tags寫入SELECT COUNT(DISTINCT ImageId) FROM Tags以獲取計數,在LINQ中,我_context.Tags.Select(t => t.Image).Distinct().Count()_context.Tags.Select(t => t.Image).Distinct().Count() 但是該LINQ查詢似乎導致EF-Core聯接兩個表,返回所有行,然后在代碼中執行DistinctCount

我嘗試做_context.Tags.FromSql("SELECT COUNT(DISTINCT ImageId) FROM Tags") ,但是因為該查詢僅返回計數,所以調用失敗,因為EF無法將結果映射到Tag。 我還嘗試使用_context.Database.FromSql<int> ,但是找不到任何真實的文檔,而且似乎也沒有IntelliSense。

我現在所做的是Eric Anderson撰寫的此博客文章的“ ADO.NET”部分中詳細介紹的內容:

int count;
using (var connection = _context.Database.GetDbConnection())
{
    connection.Open();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "SELECT COUNT(DISTINCT ImageId) FROM Tags";
        string result = command.ExecuteScalar().ToString();

        int.TryParse(result, out count);
    }
}

但這是有效地獲得計數的最佳方法嗎?


編輯:這是EF放入Debug輸出的查詢:

SELECT "t"."TagId", "t"."Content", "t"."ImageId", "t.Image"."ImageId", "t.Image"."FileName", "t.Image"."Path", "t.Image"."Url"
FROM "Tags" AS "t"
LEFT JOIN "Images" AS "t.Image" ON "t"."ImageId" = "t.Image"."ImageId"
ORDER BY "t"."ImageId"

到目前為止,您無法定義即席結果。 好消息是它目前正在積壓中: https//github.com/aspnet/EntityFramework/issues/1862

同時,這是一個可行的擴展方法:

public static int IntFromSQL(this ApplicationDbContext context, string sql )
{
    int count;
    using (var connection = context.Database.GetDbConnection())
    {
        connection.Open();

        using (var command = connection.CreateCommand())
        {
            command.CommandText = sql;
            string result = command.ExecuteScalar().ToString();

            int.TryParse(result, out count);
        }
    }
    return count;
}

用法:

int result = _context.IntFromSQL("SELECT COUNT(DISTINCT ImageId) FROM Tags");

您的原始代碼行應該已經完全完成了您想要的工作。 還建議通過內聯SQL使用。

_context.Tags.Select(t => t.Image).Distinct().Count()

您確定這會調用兩個表的數據庫,然后在內存中查詢它們嗎? 如果在調試時觀察到此行為,則可能是您的檢查導致IQueryable枚舉的,該枚舉將使用與其他情況不同的查詢來調用數據庫。

在不中斷正在運行的代碼的情況下,一種檢查實際查詢的方法是使用Entity Framework Core文檔中的MyLoggerProvider

https://docs.efproject.net/en/latest/miscellaneous/logging.html?highlight=logging

在代碼中注冊記錄器后,針對服務器運行的任何SQL查詢都將顯示在控制台窗口和/或文件c:\\ temp \\ log.txt中。

在網站示例的數據庫表上使用Distinct()和Count()時,生成了以下日志消息。

SELECT COUNT(*)
FROM (
SELECT DISTINCT [a.Blog].[BlogId], [a.Blog].[Url]
FROM [Posts] AS [a]
INNER JOIN [Blogs] AS [a.Blog] ON [a].[BlogId] = [a.Blog].[BlogId]
) AS [t]Closing connection to database '***' on server 'tcp:**************'.

最后,由於不需要t.Image上的任何屬性,因此似乎應該使用Where()而不是Select()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM