這是今天在實際項目中遇到的一個問題,Entity Framework Core 2.2 生成了下面的 SQL 語句,INNER JOIN 部分丑陋的 SQL 語句讓人無法忍受。
SELECT TOP(@__p_1) [t].[ShortName] AS [EnterpriseShortName], [j].[Key], [j].[PositionName] FROM [JobPosition] AS [j] INNER JOIN ( SELECT [e].* FROM [Offer].[Enterprise] AS [e] WHERE [e].[IsActive] = 1 ) AS [t] ON [j].[EnterpriseKey] = [t].[Key] WHERE ((([j].[Status] = 1) AND ([t].[IsActive] = 1)) AND ([j].[ExpireDate] > GETDATE()))) AND ([j].[CategoryID] = @__categoryId_0)
使用的是標准的一對多(one-to-mant)映射關系,在其他項目都能生成賞心悅目的 SQL 語句,唯獨今天這個項目中不行。
job.HasOne(j => j.Enterprise) .WithMany(e => e.Jobs) .HasForeignKey(j => j.EnterpriseKey);
這個項目與其他項目不同的地方是用了很多 HasQueryFilter ,比如
enterprise.HasQueryFilter(e => e.IsActive);
去掉上面的 HasQueryFilter 問題就解決了,改進后生成的 SQL 語句如下
SELECT TOP(@__p_1) [j.Enterprise].[ShortName] AS [EnterpriseShortName], [j].[Key], [j].[PositionName] FROM [JobPosition] AS [j] INNER JOIN [Offer].[Enterprise] AS [j.Enterprise] ON [j].[EnterpriseKey] = [j.Enterprise].[Key] WHERE ((([j].[Status] = 1) AND ([j.Enterprise].[IsActive] = 1)) AND ([j].[ExpireDate] > GETDATE()))) AND ([j].[CategoryID] = @__categoryId_0)
使用 HasQueryFilter 要小心這個小坑。