【发布时间】:2021-08-07 09:47:25
【问题描述】:
我正在尝试使用 LINQ 链接多个值或循环。
情况
平台:.net 5C# 9
我们正在为列表构建过滤逻辑。在当前情况下,它涉及要过滤的字符串值。
用户可以搜索一个或多个值。他可以决定单个搜索词是否为 AND/OR 链接,以及某个值是否为否定。
我看到了这个条目。但由于我的值在循环中,我不能使用||。
https://stackoverflow.com/a/37195788/1847143
例子:
- 名称中带有“A”的所有动物
SELECT * FROM "Animal" WHERE "Name" = 'A'; - 名称中带有“A”或“B”的所有动物
SELECT * FROM "Animal" WHERE "Name" = 'A' OR "Name" = 'B'; - 名称中包含“A”或“B”或非“C”的所有动物(这将是毫无意义的搜索)
SELECT * FROM "Animal" WHERE "Name" = 'A' OR "Name" = 'B' OR "Name" != 'C' ; - 名称中带有“A”和“B”的所有动物
SELECT * FROM "Animal" WHERE "Name" = 'A' AND "Name" = 'B'; - 名称中包含“A”和“B”而不是“C”的所有动物
SELECT * FROM "Animal" WHERE "Name" = 'A' AND "Name" = 'B' AND "Name" != 'C';
问题
与 LINQ 的 AND 链接没有问题。但是这些值如何与 OR 联系起来呢?
代码示例
using System.Collections.Generic;
using System.Linq;
namespace SampleProject
{
public class Program
{
public static void Main(string[] args)
{
// Or Condtion
Condition condition = Condition.Or;
var animalsQuery = Animals.AsQueryable();
// Loop over all search values to extend the query
foreach (FilterValue filterValue in FilterValues)
{
switch (filterValue.LikeType)
{
case LikeType.Left: // LIKE '%value'
animalsQuery = filterValue.IsNegated
? animalsQuery.Where(animal => !animal.Name.EndsWith(filterValue.Value))
: animalsQuery.Where(animal => animal.Name.EndsWith(filterValue.Value));
break;
case LikeType.Right: // LIKE 'value%'
animalsQuery = filterValue.IsNegated
? animalsQuery.Where(animal => !animal.Name.StartsWith(filterValue.Value))
: animalsQuery.Where(animal => animal.Name.StartsWith(filterValue.Value));
break;
case LikeType.LeftAndRight: // LIKE '%value%'
animalsQuery = filterValue.IsNegated
? animalsQuery.Where(animal => !animal.Name.Contains(filterValue.Value))
: animalsQuery.Where(animal => animal.Name.Contains(filterValue.Value));
break;
case LikeType.Equals: // Like 'value'
animalsQuery = filterValue.IsNegated
? animalsQuery.Where(animal => animal.Name != filterValue.Value)
: animalsQuery.Where(animal => animal.Name == filterValue.Value);
break;
}
}
var result = animalsQuery.ToList();
}
/// Values to filter
public static List<Animal> Animals = new()
{
new() {Name = "Lenny"},
new() {Name = "Gideon"},
new() {Name = "Shania"},
new() {Name = "Jada"},
new() {Name = "Kamil"},
new() {Name = "Fariha"},
};
/// Search Values
public static List<FilterValue> FilterValues = new()
{
new() {Value = "a", LikeType = LikeType.Left},
new() {Value = "n", LikeType = LikeType.Right},
new() {Value = "f", LikeType = LikeType.LeftAndRight},
new() {Value = "k", LikeType = LikeType.Equals},
};
}
public class Animal
{
public string Name { get; set; }
}
public class FilterValue
{
public string Value { get; set; }
public bool IsNegated { get; set; }
public LikeType LikeType { get; set; }
}
public enum LikeType
{
Left = 1,
Right = 2,
LeftAndRight = 3,
Equals = 4,
}
public enum Condition
{
And = 1,
Or = 2,
}
}
【问题讨论】:
-
如果
OR都等于而不是不等于,那么问题很简单——使用Contains(即有一个List<string>的值)。!=唉,这不会那么好。 -
与其链接多个
Where调用,不如为每个条件创建一个 lambda,将这些 lambda 与&&和/或||运算符组合,然后使用组合结果进行一个Where调用. -
你可能需要一个 PredicateBuilder;即可以创建和组合 linq 查询谓词的类。它通常包括 OR、AND、NOT、XOR、TRUE 和 FALSE 的方法。它的输入是针对项目类的属性名称或 lambda getter 表达式(在您的示例中为“Animal”)。
-
@mjwills 但是这样我不能将
StartsWith与EndsWith结合起来。所有“以 A 开头”和“以 E 结尾”的动物。SELECT * FROM "Animal" WHERE "Name" LIKE 'A%' AND "Name" LIKE '%E'; -
@TheBigNeo 没错。
标签: c# linq .net-5 sql-to-linq-conversion