首页 > 解决方案 > 在 Linq 中使用 ToList() 时避免使用 NVARCHAR

问题描述

我在 Column(TypeName) 设置为 VARCHAR 的类中有一个属性,但是当 linq 使用 ToList() 时,linq 生成的 SQL 会转换为 NVARCHAR。有没有办法避免调用 ToList() 方法时发生的 nvarchar 转换?

var codes = xyz.Where(x => x.IsValid).Select(x => x.Code.ToLower()).ToList();
requests = requests.Where(p => codes.Contains(p.Type.ToLower()));
Property(c => c.Type).HasColumnType("varchar").HasMaxLength(3).IsFixedLength();

如上所示,虽然 Type 属性的列类型设置为 VARCHAR,但 linq 在使用 ToList() 时使用 NVARCHAR。

标签: sqlperformancelinqlinq-to-sqldata-conversion

解决方案


您可以构建自己的谓词:

public static class PredicateBuilder
 {
     private static readonly MethodInfo asNonUnicodeMethodInfo = 
                 typeof(EntityFunctions).GetMethod("AsNonUnicode");
     private static readonly MethodInfo stringEqualityMethodInfo = 
                 typeof(string).GetMethod("op_Equality");

     public static Expression<Func<TEntity, bool>> ContainsNonUnicodeString<TEntity>(
                 IEnumerable<string> source, 
                 Expression<Func<TEntity, string>> expression) 
     {
         if (source == null) throw new ArgumentNullException("source");
         if (expression == null) throw new ArgumentNullException("expression");

         Expression predicate = null;
         foreach (string value in source)
         {
             var fragment = Expression.Equal(
                 expression.Body, 
                 Expression.Call(null, 
                     asNonUnicodeMethodInfo, 
                     Expression.Constant(value, typeof(string))), 
                 false, 
                 stringEqualityMethodInfo);
             if (predicate == null)
             {
                 predicate = fragment;
             }
             else
             {
                 predicate = Expression.OrElse(predicate, fragment);
             }
         }

         return Expression.Lambda<Func<TEntity, bool>>(predicate,
             ((LambdaExpression)expression).Parameters);
     }
 }

在此处查看更多信息:https ://docs.microsoft.com/da-dk/archive/blogs/diego/workaround-for-performance-with-enumerable-contains-and-non-unicode-columns-against-ef-in-净4-0


推荐阅读