我有这段代码可以通过交叉数字搜索类似物,如果整个字符串匹配,它就可以工作,但只有 crossNumbers 的形式为 "021.181; 021181_SMP; 10502_SOYLU; 1202 1601; ",并且我需要检查的不是整个字符串,而是每个字符串以分号分隔的子字符串。
var query = _context.Products
.Where(p => p.CrossNumbers.Contains(crossNumbers) && p.Id != selectedProduct);
var totalItems = await query.CountAsync();
例如,以下是我尝试的选项,结果之一 - 无法翻译:
var crossNumbersArray = crossNumbers.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(cn => cn.Trim())
.ToArray();
var query = _context.Products
.Where(p => crossNumbersArray.Any(cn => p.CrossNumbers.Contains(cn)) && p.Id != selectedProduct);
var crossNumberList = crossNumbers.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(cn => cn.Trim())
.ToList();
var query = _context.Products
.AsEnumerable()
.Where(p => crossNumberList.Any(cn => p.CrossNumbers.Contains(cn)) && p.Id != selectedProduct);
var crossNumberArray = crossNumbers.Split(';', StringSplitOptions.RemoveEmptyEntries);
var query = _context.Products
.Where(p => crossNumberArray.Any(cn => EF.Functions.Like(p.CrossNumbers, "%" + cn + "%")) && p.Id != selectedProduct);
var crossNumberArray = crossNumbers.Split(';', StringSplitOptions.RemoveEmptyEntries);
var query = _context.Products
.Where(p => crossNumberArray.Any(cn => p.CrossNumbers.Contains(";" + cn + ";")) && p.Id != selectedProduct);
您不能将 Enumerable 和 Queryable 组合在一个查询中。您需要将数据库查询拖到内存中(并使其可枚举),或者将列表传递给查询。
如果数据库很大,搜索列表很小,那么第二种自然更优化。
还有第三个选项 - 迭代列表并搜索数据库中的每个元素。
在 Entity Framework 8 中,您可以在属性中使用基本类型的集合。
我建议稍微更改属性
CrossNumbers,使其成为一个数组(或任何其他合适的集合):在数据库中,这将作为 JSON 数组存储在类型为 的列中
NVARCHAR(MAX)。在保存到数据库之前,必须将字符串拆分为数组。我们只是使用它
Split(';')。现在查询变得很容易。我们简单地使用两个集合相交
Intersect并检查是否至少有一个匹配:Any。你可以这样写条件:
EF 生成一个带有
OPENJSON.