C# 自定义查询扩展,可与NHibernate一起使用
我正在尝试编写一个自定义Linq扩展,它也可以在DB中执行 基本上,我想做的是C# 自定义查询扩展,可与NHibernate一起使用,c#,linq,nhibernate,linq-to-nhibernate,C#,Linq,Nhibernate,Linq To Nhibernate,我正在尝试编写一个自定义Linq扩展,它也可以在DB中执行 基本上,我想做的是collectionOfStrings.Where(x=>!x.IsNullOrWhiteSpace)不幸的是,它不受支持 ==================到目前为止我都试过了============= 这一部分只对那些可能提出除以下想法之外的另一个想法的人感兴趣 这样做有一个解决方法collection.Where(x=>x!=null&&x.Trim()!=string.Empty),但由于我经常使用它,它不是
collectionOfStrings.Where(x=>!x.IsNullOrWhiteSpace)
不幸的是,它不受支持
==================到目前为止我都试过了=============
这一部分只对那些可能提出除以下想法之外的另一个想法的人感兴趣
这样做有一个解决方法collection.Where(x=>x!=null&&x.Trim()!=string.Empty)
,但由于我经常使用它,它不是最好的解决方案
最漂亮的解决方案是,找到一种方法来编写一个字符串扩展名IsNullOrWhiteSpaceDB
,它可以工作,或者以编程方式将IsNullOrWhiteSpace
方法添加到数据库中以确保支持
这是我试图创建一个有效的IsNullOrWhiteSpace
方法,但它也不受支持:
public static bool IsNullOrWhiteSpaceDB(this string? str) =>
str == null || str.Trim() == String.Empty;
所以我开始写一个谓词,它工作得很好:
public IQueryable<string> GetAll() =>
GetAll().Select(x => x.property).Where(StringIsNotNullOrWhiteSpace).Distinct();
private static Expression<Func<string?, bool>> StringIsNotNullOrWhiteSpace =>
x => x != null && x.Trim() != string.Empty;
“原始版本”也会抛出相同的错误,因此我认为可能是创建的表达式((x==null)或(x.Trim()==“”)
(从调试器复制)。对我来说,它实际上看起来相当好,我不明白错误的原因
有什么想法吗?我会很高兴的 不需要为此构建表达式。您只需要一个扩展方法,它接受并返回
IQueryable
公共静态类扩展
{
公共静态IQueryable IsNullOrWhiteSpaceDB(此IQueryable输入)
{
返回输入。其中(x=>x!=null和&x.Trim()!=string.Empty);
}
}
不需要为此构建表达式。您只需要一个扩展方法,它接受并返回IQueryable
公共静态类扩展
{
公共静态IQueryable IsNullOrWhiteSpaceDB(此IQueryable输入)
{
返回输入。其中(x=>x!=null和&x.Trim()!=string.Empty);
}
}
我已经为LINQKit创建了PR,这将简化您的生活
其思想是将ExpandableAttribute
添加到这些方法中,这些方法指向带有替换表达式的静态函数
公共静态类扩展
{
[可扩展(名称(IsNotNullOrWhiteSpaceDBImpl))]
公共静态bool IsNotNullOrWhiteSpaceDB(字符串str)
=>抛出新的NotImplementedException();
公共静态表达式IsNotNullOrWhiteSpaceDBImpl()
=>x=>x!=null&&x.Trim()!=string.Empty;
}
所以查询应该至少使用一次AsExpandable()
。将此调用放在存储库中的某个位置
db.Users.AsExpandable()
.Where(u=>u.FirstName.IsNotNullOrWhiteSpaceDB()| | u.MiddleName.IsNotNullOrWhiteSpaceDB())
我已经为LINQKit创建了PR,这将简化您的生活
其思想是将ExpandableAttribute
添加到这些方法中,这些方法指向带有替换表达式的静态函数
公共静态类扩展
{
[可扩展(名称(IsNotNullOrWhiteSpaceDBImpl))]
公共静态bool IsNotNullOrWhiteSpaceDB(字符串str)
=>抛出新的NotImplementedException();
公共静态表达式IsNotNullOrWhiteSpaceDBImpl()
=>x=>x!=null&&x.Trim()!=string.Empty;
}
所以查询应该至少使用一次AsExpandable()
。将此调用放在存储库中的某个位置
db.Users.AsExpandable()
.Where(u=>u.FirstName.IsNotNullOrWhiteSpaceDB()| | u.MiddleName.IsNotNullOrWhiteSpaceDB())
感谢您的努力和建议!它只是与EntityFramework一起工作还是与NHibernate一起工作?因为我们不使用EntityFramework,它可以与任何LINQ提供程序一起使用。最好自己来编这篇文章。谢谢你的努力和建议!它只是与EntityFramework一起工作还是与NHibernate一起工作?因为我们不使用EntityFramework,它可以与任何LINQ提供程序一起使用。最好自己编译这个分支。
public class QueryVisitor : ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.IsStatic && node.Method.Name == "IsNullOrWhiteSpace")
{
//!(b.Diameter == null || b.Diameter.Trim() == string.Empty)
var arg = node.Arguments[0];
var argTrim = Expression.Call(arg, typeof(string).GetMethod("Trim", Type.EmptyTypes));
var exp = Expression.MakeBinary(ExpressionType.Or,
Expression.MakeBinary(ExpressionType.Equal, arg, Expression.Constant(null, arg.Type)),
Expression.MakeBinary(ExpressionType.Equal, argTrim, Expression.Constant(string.Empty, arg.Type))
);
return exp;
}
return base.VisitMethodCall(node);
}
}
public static class EfQueryableExtensions
{
public static IQueryable<T> WhereEx<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> where)
{
var visitor = new QueryVisitor();
return queryable.Where(visitor.VisitAndConvert(where, "WhereEx"));
}
}
public static class QueryHelper
{
public static IQueryable<T> WhereIsNotNullOrWhiteSpace<T>(this IQueryable<T> query, Expression<Func<T, string?>> expression)
{
var arg = expression.Body;
var argTrim = Expression.Call(arg, typeof(string).GetMethod("Trim", Type.EmptyTypes));
var exp = Expression.MakeBinary(ExpressionType.And,
Expression.MakeBinary(ExpressionType.NotEqual, arg, Expression.Constant(null, arg.Type)),
Expression.MakeBinary(ExpressionType.NotEqual, argTrim, Expression.Constant(string.Empty, arg.Type))
);
var lambda = Expression.Lambda<Func<T, bool>>(exp, expression.Parameters);
var result = query.Where(lambda);
return result;
}
}
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException: A recognition error occurred.
public static class Extensions
{
public static IQueryable<string> IsNullOrWhiteSpaceDB(this IQueryable<string> input)
{
return input.Where(x => x != null && x.Trim() != string.Empty);
}
}