[英]Clean a column value from an Entity Framework table
I need to clean the value of a column in C# using linq. 我需要使用linq在C#中清除列的值。
Here is an example: 这是一个例子:
var p_name = "michaelscott";
var result = db.tablename.where(x => x.name
.Replace(" ",'')
.Replace("$","")
== p_name).FirstOrDefault();
This example only uses 2 items (spaces and dollar sign). 本示例仅使用2个项目(空格和美元符号)。 if I wanted to add more things to clean, the linq query would be enormous, so I tried writing a method but it throws an error that this wasn't allowed.
如果我想添加更多要清除的内容,则linq查询将非常庞大,因此我尝试编写一种方法,但会引发错误,这是不允许的。 I then tried writing an extension class that did all the replaces with in it but it errors out with the same error as using a method.
然后,我尝试编写一个扩展类,在其中进行了所有替换,但错误出与使用方法相同的错误。
Is there a way to do this without having to use a .Replace
for each character I want to remove? 有没有一种方法,而不必为要删除的每个字符使用
.Replace
?
Run an ad-hoc query within EF to easily acomplish what you're trying to do. 在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);
Replaced with (I think) a better answer. 用(我认为)更好的答案代替。
You can write a method to generate the proper Expression
to represent the cleaned-up value using an ExpressionVisitor
. 您可以使用
ExpressionVisitor
编写一种方法来生成适当的Expression
来表示清理后的值。 The easiest way to use it is to write a new version of Where
so that type inference will work for you. 使用它的最简单方法是编写
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());
}
With the extension code in place, using it is relatively easy: 有了扩展代码,使用它相对容易:
var p_name = "michaelscott";
var result = db.tablename
.WhereRemoveAll(x => x.name.RemoveAll("$ ") == p_name)
.FirstOrDefault();
A more general approach might use something like LINQKit's approach to modify the query and automatically expand all embedded methods with some attribute - I added some code using this approach on CodeReview here . 更通用的方法可能使用类似LINQKit的方法来修改查询并自动扩展具有某些属性的所有嵌入式方法-我在此处的 CodeReview上使用此方法添加了一些代码。
you can use a Regex expression to catch all the characters you'd like to replace 您可以使用Regex表达式捕获要替换的所有字符
var result = db.tablename(x =>
Regex.Replace(x, @"[^\w]", "")
== p_name).FirstOrDefault();
The above expression will remove all chars that are not a letter or number 上面的表达式将删除所有不是字母或数字的字符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.