如何使用EF Core 2.1从数据库中找到与模式匹配的最高价值?

时间:2019-04-05 14:54:34

标签: c# .net-core ef-core-2.2 .net-core-2.2

我正在使用Entity Framework Core 2.1在SQL中存储一个称为“设备”的表。该表具有称为“标签”的列。我有一个名为Equipment的类,其中Label为字符串属性。

根据用户输入,该Label属性有时可以具有#[0-9][0-9][0-9][0-9][0-9]的模式。

如何使用EF Core 2.1快速而干净地从SQL表中找到与“设备”表中的模式匹配的最高“标签”值?

var myContext = CreateDbContext();
string resultIdentifier;

        // if there is any item in the equipment table
        if (myContext.equipment.Any()) {
            var regexStr = @"^[#]+(0-9{5})$";  //TODO: how to create this regex string correctly?

            // find for any matching pattern in label column using regex
            var listFound = myContext.equipment.Where(mp => Regex.IsMatch(mp.Label, regexStr)).ToList();

            if (listFound.Any()) {
                //TODO: how to find the maximum from the pattern?
            }
            else {
                _logger.Trace("No highest label is found because no matched pattern is found.");
                resultIdentifier = null;
            }
        }
        else {
            _logger.Trace("No highest label is found because no entry in equipment table.");
            resultIdentifier = null;
        }

1)如何创建正确的Regex搜索字符串匹配模式#[0-9][0-9][0-9][0-9][0-9]

2)正则表达式是寻找最高标签样式的最佳方法吗?

3)如何使用EF Core方法从SQL表中找到最高标签模式?

谢谢

1 个答案:

答案 0 :(得分:0)

使用正则表达式将效率低下。 EF无法将Regex.IsMatch转换为相应的SQL表达式,因此它将首先获取整个设备表,然后将正则表达式应用于表中的每一行。

相反,SQL Server具有类似正则表达式的模式和通配符,可在使用LIKE的查询中使用它们。

请考虑以下内容:

DECLARE @foo TABLE (
    label varchar(10) null
)

INSERT @foo
SELECT '#12345'  -- 'Lowest'
UNION 
SELECT '#99999'  -- 'Highest'
UNION 
SELECT '#999999' -- 'Too Many Characters
UNION
SELECT '#123'    -- 'Not Enough Characters' 
UNION 
SELECT '#abcde1' -- 'Not the Right Characters'
UNION
SELECT '12345'   -- 'No Leading #'
SELECT label 
  FROM @foo 
 WHERE label LIKE '[#][0-9][0-9][0-9][0-9][0-9]'

将返回与您的模式匹配的行(#字符本身是通配符,因此将其括在方括号中以指示它是文字):

label
=====
#12345
#99999
SELECT TOP 1 label 
  FROM @foo 
 WHERE label LIKE '[#][0-9][0-9][0-9][0-9][0-9]'
 ORDER BY label desc

将按从高到低的顺序对您的结果进行排序:

label
=====
#99999
#12345

并添加TOP 1将返回第一行:

label
=====
#99999

在EF Core中有几种使用此方法的方法,但是最简单的方法就是简单地使用raw SQL query

string sql = @"SELECT TOP 1 * 
  FROM @foo 
 WHERE label LIKE '[#][0-9][0-9][0-9][0-9][0-9]'
 ORDER BY label desc";

var foundRows = myContext.equipment
    .FromSql(sql)
    .ToList();

if (foundRows.FirstOrDefault() != null) 
{
   //...do something...
}