Очистить значение столбца из таблицы Entity Framework - PullRequest
0 голосов
/ 18 января 2019

Мне нужно очистить значение столбца в C # с помощью linq.

Вот пример:

var p_name = "michaelscott";
var result = db.tablename.where(x => x.name
        .Replace(" ",'')
        .Replace("$","") 
        == p_name).FirstOrDefault();

В этом примере используются только 2 элемента (пробелы и знак доллара). если бы я хотел добавить больше вещей для очистки, запрос linq был бы огромным, поэтому я попытался написать метод, но он выдает ошибку, что это не разрешено. Затем я попытался написать класс расширения, в котором были выполнены все замены, но он выдает ошибку с той же ошибкой, что и при использовании метода.

Есть ли способ сделать это без необходимости использовать .Replace для каждого символа, который я хочу удалить?

Ответы [ 3 ]

0 голосов
/ 18 января 2019

Вы можете использовать выражение Regex, чтобы поймать все символы, которые вы хотите заменить

 var result = db.tablename(x => 
                Regex.Replace(x, @"[^\w]", "")
          == p_name).FirstOrDefault();

Приведенное выше выражение удалит все символы, которые не являются буквой или цифрой

0 голосов
/ 18 января 2019

Заменено (я думаю) лучшим ответом.

Вы можете написать метод для генерации правильного Expression для представления очищенного значения с использованием ExpressionVisitor. Самый простой способ его использования - написать новую версию Where, чтобы вывод типа работал для вас.

public static class IQueryableExt {
    // body only for LINQ to Objects use
    public static string RemoveAll(this string src, string removeChars) => removeChars.Aggregate(src, (ans,ch) => ans.Replace(ch.ToString(), ""));

    private static Expression CleanUp(this Expression dbFn, string charsToRemove) {
        var toCharE = Expression.Constant(String.Empty);
        var replaceMI = typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) });

        var methodBody = dbFn;
        foreach (var ch in charsToRemove)
            methodBody = Expression.Call(methodBody, replaceMI, Expression.Constant(ch.ToString()), toCharE);

        return methodBody;
    }

    /// <summary>
    /// ExpressionVisitor to expand x.RemoveAll("x..z") to x.Replace("x","")...Replace("z","") in
    /// an Expression.
    /// </summary>
    private class RemoveAllVisitor : ExpressionVisitor {
        public override Expression Visit(Expression node) {
            if (node?.NodeType == ExpressionType.Call) {
                var callnode = (MethodCallExpression)node;
                if (callnode.Method.Name == "RemoveAll" && callnode.Method.DeclaringType == typeof(IQueryableExt))
                    if (callnode.Arguments[1] is ConstantExpression ce && ce.Type == typeof(string))
                        return callnode.Arguments[0].CleanUp(ce.Value.ToString());
            }

            return base.Visit(node);
        }
    }

    private static T ExpandRemoveAll<T>(this T orig) where T : Expression => (T)new RemoveAllVisitor().Visit(orig);

    public static IQueryable<T> WhereRemoveAll<T>(this IQueryable<T> src, Expression<Func<T, bool>> predFn) => src.Where(predFn.ExpandRemoveAll());
}

При наличии кода расширения использовать его относительно просто:

var p_name = "michaelscott";
var result = db.tablename
                 .WhereRemoveAll(x => x.name.RemoveAll("$ ") == p_name)
                 .FirstOrDefault();

Более общий подход может использовать что-то вроде подхода LINQKit для изменения запроса и автоматического расширения всех встроенных методов с некоторым атрибутом - я добавил некоторый код, используя этот подход, в CodeReview здесь .

0 голосов
/ 18 января 2019

Запустите специальный запрос в EF, чтобы легко выполнить то, что вы пытаетесь сделать.

var cmd = "UPDATE dbo.TableName SET Name = REPLACE(REPLACE(t.Column, ' ', ''), '$', '')";
    cmd += "FROM Table t";
    cmd += "WHERE t.Name = value;";

context.Database.ExecuteSqlCommand(cmd);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...