C#LINQ如何检查变量是否以" M ####"其中#是数字

时间:2016-10-25 08:16:32

标签: c# entity-framework linq

我正在创建一个链接到GitLab的更改日志Web应用程序,它从数据库表中获取数据,只要有推送GitLab就会更新。

为了进行推送,我们在消息区域添加一个自定义ID,后跟可能是任何内容的消息。此自定义ID必须是;中号#### / C ##### /合并/还原。其中#表示数值(0-9)。

应用程序必须识别每个推送的ID,以便以后可以用于过滤等。

之前我已经使用此代码仅选择M ####和C #####,但一旦选择'合并'被用作它也会显示的ID。

var query = from c in db.Clgcom
    where c.Prjid == 7
    && (c.Modid.StartsWith("C")
    || c.Modid.StartsWith("M"))
    select c.Modid;

结果:

M1234, M2345, C12345, M0000, C75843, Merge

使用.StartsWith("M####")并不起作用,除了使用10种不同的案例外,我还不知道如何解决这个问题;

where c.Modid.StartsWith("M0")
|| c.Modid.StartsWith("M1")
|| c.Modid.StartsWith("M2")
|| c.Modid.StartsWith("M3")
// etc.

有没有更好的方法来解决我的问题?

编辑:我使用的是实体框架,因此正则表达式可能会导致问题。

2 个答案:

答案 0 :(得分:4)

如果定位SQL Server,则可以使用SqlFunctions.PatIndex。与string.Contains的EF映射不同,PatIndex支持LIKE语法。

  

返回指定表达式中第一次出现 [LIKE]模式的起始位置。

值为1表示"匹配第一个字符"。

var query = from c in db.Clgcom
    where c.Prjid == 7
      && SqlFunctions.PatIndex("M[0-9][0-9][0-9][0-9]", c.Modid) == 1
    select c.Modid;

与LIKE一样,SQL Server能够利用PatIndex进行索引 - 在这种情况下,由于固定的锚定" M"开始。实际的计划选择可能会有所不同。

另一种选择是将其拉到客户端并使用正则表达式或其他方式使用Linq 2对象。如果边缘情况的百分比很低,这仍然可以在几乎没有性能影响的情况下完成。因为原始查询受到限制,所以大多数工作都是在SQL中完成的,可以应用适当的索引。

var query = (from c in db.Clgcom
    where c.Prjid == 7
      && c.Modid.StartsWith("M") // .. LIKE "M%"
    select c.Modid)
    .ToList(); // -> IList<string>, in L2O land

// I'm a fan of this syntax :}
var re = new Regex(@"^M\d{4}", RegexOptions.IgnoreCase);
var finalClientFilter = query
    .Where(s => re.IsMatch(s));

请参阅Like Operator in Entity Framework?了解hullaballo。

答案 1 :(得分:1)

如果您确定#pragma omp parallel shared(mfield)值的域名与您在原始问题中的设置完全相同,那么您只需检查不需要的已知值,通过消除,表示余数将匹配ModidM...,如果您使用索引(C...在数据库中相当便宜),查询将会快速有效。

StartsWith

但是如果你不能做出这种保证,那么你将不得不使用IQueryable<String> query = db.Clgcom .Where( c => c.Prjid == 7 && c.Modid != "Merge" && ( c.Modid.StartsWith("M") || c.Modid.StartsWith("C") ) ) .Select( c => c.Modid ); PATINDEX将其公开给EF。