Избегайте NVARCHAR при использовании ToList () в Linq - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть свойство в классе с Column (TypeName), установленным в VARCHAR, но когда linq использует ToList (), SQL, сгенерированный linq, конвертируется в NVARCHAR. Есть ли способ избежать преобразования nvarchar, которое происходит при вызове метода ToList ()?

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 использует NVARCHAR, когда ToList () используется.

1 Ответ

0 голосов
/ 09 апреля 2020

Вы можете создать свой собственный предикат:

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-net-4-0

...