Entity Framework性能优化

时间:2021-01-03 05:59:25

AsNonUnicode

执行如下语句,并用SqlProfiler监控其SQL:

            var list = WMFactory.ReChargeMobile.Queryable().Where(w => w.InterfaceId == guid && w.MsgId == "xxx")
                .Select(s => new
                {
                    AgentId = s.AgentId,
                    PackageName = s.PackageName
                })
                .ToList();

生成SQL如下:

SELECT 1                       AS [C1],
       [Extent1].[AgentId]     AS [AgentId],
       [Extent1].[PackageName] AS [PackageName]
FROM   [dbo].[FL_ReChargeMobile] AS [Extent1]
WHERE  ([Extent1].[InterfaceId] = 'f97317a1-21e1-4a6e-b1f9-960fc1def7eb' /* @p__linq__0 */)
       AND (N'xxx' = [Extent1].[MsgId])

下面将语句换成如下:

            var list = WMFactory.ReChargeMobile.Queryable().Where(w => w.InterfaceId == guid && w.MsgId == EntityFunctions.AsNonUnicode("xxx"))
                .Select(s => new
                {
                    AgentId = s.AgentId,
                    PackageName = s.PackageName
                })
                .ToList();

生成SQL如下:

SELECT 1                       AS [C1],
       [Extent1].[AgentId]     AS [AgentId],
       [Extent1].[PackageName] AS [PackageName]
FROM   [dbo].[FL_ReChargeMobile] AS [Extent1]
WHERE  ([Extent1].[InterfaceId] = '610a6980-7f90-4f48-83d1-def8ef3db13e' /* @p__linq__0 */)
       AND ('xxx' = [Extent1].[MsgId])

相信你也看出其中生成的SQL语句区别了,一个加了N,一个未加N,都知道N是将字符串作为Unicode格式进行存储。因为.Net字符串是Unicode格式,在SQL中Where子句中当一侧有N型而另一侧没有N型时,此时会进行数据转换,也就是说如果你在表中建立了索引此时会失效代替的是造成全表扫描。用 EntityFunctions.AsNonUnicode 方法来告诉.Net 将其作为一个非Unicode来对待,此时生成的SQL语句两侧都没有N型,就不会进行更多的数据转换,也就是说不会造成更多的全表扫描。所以当有大量数据时如果不进行转换会造成意想不到的结果,因此在进行字符串查找或者比较时建议用AsNonUnicode()方法来提高查询性能。