我正在创建一个链接到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.
有没有更好的方法来解决我的问题?
编辑:我使用的是实体框架,因此正则表达式可能会导致问题。
答案 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)
值的域名与您在原始问题中的设置完全相同,那么您只需检查不需要的已知值,通过消除,表示余数将匹配Modid
和M...
,如果您使用索引(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。