C# 构建where子句体
我试图找到一种方法来构建where子句并将其传递给repository Get()方法。它应该过滤名称以特定字母开头的项目。我能够构造Where子句主体的一部分,但找不到处理项目名称不以字母开头的场景的方法。例如:C# 构建where子句体,c#,linq,entity-framework,collections,C#,Linq,Entity Framework,Collections,我试图找到一种方法来构建where子句并将其传递给repository Get()方法。它应该过滤名称以特定字母开头的项目。我能够构造Where子句主体的一部分,但找不到处理项目名称不以字母开头的场景的方法。例如:\u ItemName或97\u SomeName 因此,以下是我的方法: protected override Expression<Func<DataSetSettings, bool>> GetWhereClause() { //The user
\u ItemName
或97\u SomeName
因此,以下是我的方法:
protected override Expression<Func<DataSetSettings, bool>> GetWhereClause()
{
//The user has selected FilterLetter, for example: "A"
// return all items which name starts with "A"
if (!string.IsNullOrWhiteSpace(FilterLetter) && !FilterLetter.Equals("All"))
return (x => x.Name.StartsWith(FilterLetter) && x.Type == Type);
if (FilterLetter.Equals("Other"))
{
//Here i need to extract all items which name does not start with letter
}
//return All items of the current type
return x => x.Type == Type;
}
受保护的重写表达式getWhere子句()
{
//用户已选择FilterLitter,例如:“A”
//返回名称以“A”开头的所有项目
如果(!string.IsNullOrWhiteSpace(FilterLetter)和&!FilterLetter.Equals(“全部”))
返回(x=>x.Name.StartsWith(FilterLetter)和&x.Type==Type);
if(过滤器长度等于(“其他”))
{
//在这里,我需要提取所有名称不以字母开头的项目
}
//返回当前类型的所有项
返回x=>x.Type==Type;
}
我将感谢任何帮助!谢谢 你可以在开始时使用 像这样:
return(x=>x.Name.StartsWith(FilterLetter)==false&&x.Type==Type)代码>我的建议是对列表中的所有类型进行1db调用,然后使用linq查询该列表。您的示例是进行两次db调用
List<Type> allTypes = new List<Type>();
List<Type> typesWithA = new List<Type>();
List<Type> typesWOA = new List<Type>();
// make one db call
allTypes = entities.Types.ToList();
typesWithA = allTypes.Where(x => x.Name.StartsWith(FilterLetter)).ToList();
typesWOA = allTypes.Where(x => !x.Name.StartsWith(FilterLetter)).ToList();
List allTypes=new List();
列表类型为新列表();
列表类型WAA=新列表();
//打一个db电话
allTypes=entities.Types.ToList();
typesWithA=allTypes.Where(x=>x.Name.StartsWith(FilterLetter)).ToList();
typesWOA=allTypes.Where(x=>!x.Name.StartsWith(FilterLetter)).ToList();
现在我了解了您的需求,我四处看看,没有找到一个合适的解决方案。复杂的字符串模式匹配似乎是EF的一个弱点
我能看到的唯一方法是对照每个字母进行比较,即:
!x.Name.StartsWith("A") && !x.Name.StartsWith("B") && //on and on to Z
或确保将整个列表加载到内存中,然后使用正则表达式进行筛选:
protected override Expression<Func<DataSetSettings, bool>> GetWhereClause()
{
var noletter = new Regex("^[^a-z].*", RegexOptions.IgnoreCase);
return (
x => x.Type == Type && (
string.IsNullOrWhiteSpace(FilterLetter) ||
FilterLetter == "All" ||
(FilterType == "Other" && noletter.IsMatch(x.Name)) ||
x.Name.StartsWith(FilterType)
)
);
}
受保护的重写表达式getWhere子句()
{
var noletter=newregex(“^a-z].*”,RegexOptions.IgnoreCase);
返回(
x=>x.Type==Type&&(
string.IsNullOrWhiteSpace(FilterLetter)|
FilterLetter==“所有”|
(FilterType==“其他”&&noletter.IsMatch(x.Name))||
x、 Name.StartsWith(FilterType)
)
);
}
如果您最终选择将所有内容加载到内存中,那么至少可以先根据x.Type
进行过滤。这似乎是过滤中的共同点。至少这样,您不必将整个表加载到内存中。您使用的是Linq to SQL或实体框架,还是用于内存集合?我使用的是实体框架。您是否先尝试了一些操作,但出现了错误?我不认为实体有一个与
等效的StartsWith
。我四处查看了一下,没有发现任何关于EF中复杂模式匹配的有用信息。我在下面发布了一个建议答案。如果Types
是一个大表,这可能会对性能造成重大影响。正确。他必须想出另一种过滤器,这样他就不会拉太多的行了。这是行不通的。如果用户选择“其他”进行过滤,那么我需要带上名称不以字母开头的所有项目。示例:\u Asd,12 name,*1 othername
@您说的是“字母”,但您的示例是字符串。是单个字符还是多个字符不能位于值的开头?@vortex Nevermind。我现在明白了。你是说非字母字符。所以不是A-Z,而是数字和字符。@jwatts1980,它是带字符串的字母过滤器:A、B、C……,其他,全部。如果用户单击“A”,我将筛选项目并仅显示名称以A开头的项目。如果用户单击“其他”,我需要显示我在前面的评论中提到的项目-\u Asd,12Name,*1其他名称
,感谢您的回答。我已经有了内存收集过滤的解决方案。我希望找到一种在数据库级别实现这一点的方法。SQL Server支持正则表达式,但Entity Framework和Linq to SQL没有对它们的翻译。你所能做的就是模拟LIKE
操作符,这是包含的和StartsWith
在引擎盖下使用的操作符。现在我将使用你的解决方案与regex匹配。再次感谢。