如何解决SQL LINQ评估逗号分隔的字符串包含值
我正在使用EFCore Linq并遇到问题。我有一个存储逗号分隔的字符串的表,我需要在where子句中使用它来仅过滤包含某些值的字符串。这是我的Linq:
var volunteers = context.Volunteers
.Where(x => x.StatusId == 1
&& x.RoleIds.Split(',',StringSplitOptions.None).Contains("1")
).ToList();
该列是RoleIds。我收到的错误是Linq查询无法翻译。我在这里需要做什么?谢谢!
解决方法
如果可以使用LINQKit(或滚动自己的重点版本),则可以创建扩展来为您处理测试:
public static class IQueryableExt { // using LINQKit
// string fieldExpr(T row) - function returning multiple value string field to test
// delimiter - string separator between values in test field
// value - string value to find in values of test field
// dbq.Where(r => fieldExpr(r).Split(delimiter).Contains(value))
public static IQueryable<T> WhereSplitContains<T>(this IQueryable<T> dbq,Expression<Func<T,string>> fieldExpr,string delimiter,string value) {
var pred = PredicateBuilder.New<T>(r => fieldExpr.Invoke(r) == value);
pred = pred.Or(r => fieldExpr.Invoke(r).StartsWith(value + delimiter));
pred = pred.Or(r => fieldExpr.Invoke(r).EndsWith(delimiter + value));
pred = pred.Or(r => fieldExpr.Invoke(r).Contains(delimiter + value + delimiter));
return dbq.Where((Expression<Func<T,bool>>)pred.Expand());
}
// values - string values,one of which to find in values of test field
// string fieldExpr(T row) - function returning multiple value string field to test
// delimiter - string separator between values in test field
// dbq.Where(r => values.Any(value => fieldExpr(r).Split(delimiter).Contains(value)))
public static IQueryable<T> WhereAnySplitContains<T>(this IQueryable<T> dbq,IEnumerable<string> values,string delimiter) {
var pred = PredicateBuilder.New<T>();
foreach (var value in values) {
pred = pred.Or(r => fieldExpr.Invoke(r) == value);
pred = pred.Or(r => fieldExpr.Invoke(r).StartsWith(value + delimiter));
pred = pred.Or(r => fieldExpr.Invoke(r).EndsWith(delimiter + value));
pred = pred.Or(r => fieldExpr.Invoke(r).Contains(delimiter + value + delimiter));
}
return dbq.Where((Expression<Func<T,bool>>)pred.Expand());
}
public static IQueryable<T> WhereSplitContainsAny<T>(this IQueryable<T> dbq,IEnumerable<string> values) =>
dbq.WhereAnySplitContains(values,fieldExpr,delimiter);
public static IQueryable<T> WhereSplitContainsAny<T>(this IQueryable<T> dbq,params string[] values) =>
dbq.WhereAnySplitContains(values,delimiter);
// values - string values,all of which to find in values of test field
// string fieldExpr(T row) - function returning multiple value string field to test
// delimiter - string separator between values in test field
// dbq.Where(r => values.All(value => fieldExpr(r).Split(delimiter).Contains(value)))
public static IQueryable<T> WhereAllSplitContains<T>(this IQueryable<T> dbq,string delimiter) {
var pred = PredicateBuilder.New<T>();
foreach (var value in values) {
var subPred = PredicateBuilder.New<T>(r => fieldExpr.Invoke(r) == value);
subPred = subPred.Or(r => fieldExpr.Invoke(r).StartsWith(value + delimiter));
subPred = subPred.Or(r => fieldExpr.Invoke(r).EndsWith(delimiter + value));
subPred = subPred.Or(r => fieldExpr.Invoke(r).Contains(delimiter + value + delimiter));
pred = pred.And(subPred);
}
return dbq.Where((Expression<Func<T,bool>>)pred.Expand());
}
public static IQueryable<T> WhereSplitContainsAll<T>(this IQueryable<T> dbq,IEnumerable<string> values) =>
dbq.WhereAllSplitContains(values,delimiter);
public static IQueryable<T> WhereSplitContainsAll<T>(this IQueryable<T> dbq,params string[] values) =>
dbq.WhereAllSplitContains(values,delimiter);
}
使用这些扩展名,您的查询将是:
var volunteers = context.Volunteers.Where(x => x.StatusId == 1)
.WhereSplitContains(r => r.RoleIds,","1")
.ToList();
如果您有多个值,则可以使用其他变体:
var volunteers = context.Volunteers.Where(x => x.StatusId == 1)
.WhereSplitContainsAny(r => r.RoleIds,"1","2")
.ToList();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。