IAb*_*act 12 c# regex linq-to-sql
我有一个包含客户帐号的数据库表.在同一个表中是与生产格式不匹配的测试帐户:例如,'A1111'是生产,但'JTest'不是.我有正则表达式只会拉我的生产帐户.我需要一个特定的编译查询来只提取生产帐户.该查询按地区和日期为我提供了客户数量; 和每个地区的概念计数:
getCustomerDistribution = CompiledQuery.Compile<DataContext, String, DateTime, IEnumerable<ServerLoad>>(
(context, region, processDate) => (from cust in context.GetTable<tbl_CustomerDistro>()
where cust.ProcessedDate.Date == processDate.Date
where cust.Region == region
where Regex.IsMatch(cust.AcctNum, ProductionMask)
group cust by new
{
cust.Region,
cust.Concept
} into custDistro
orderby custDistro.Key.Region
select new CustomerDistro
(
custDistro.Key.Region,
custDistro.Key.Concept,
custDistro
.Where(c => c.Concept == custDistro.Key.Concept)
.Select(c => c.Concept).Count()
)));
Run Code Online (Sandbox Code Playgroud)
问题是我在运行时收到以下消息:
方法'Boolean IsMatch(System.String,System.String)'没有支持的SQL转换.
我在看用户定义的函数:
static Func<striing, bool> IsProduction = (AcctNum) => Regex.IsMatch(AcctNum, ProductionMask);
Run Code Online (Sandbox Code Playgroud)
这也不起作用.我不想迭代检索到的记录以进一步过滤,除非没有其他方法可以做到这一点.
有没有办法用Predicate Builder做到这一点?
我认为另一种选择是使用:
where SqlMethods.Like (cust.AcctNum, ProductionMask)
但是,我的ProductionMask是为Regex编写的:
^[B,G]\d{4}$
Run Code Online (Sandbox Code Playgroud)
有没有办法用SqlMethods.Like(...)做到这一点?
这是一个非常慢的查询.我有3个区域,这个查询运行,记录计数和返回时间是:
263:903ms
342:822ms
146:711ms
IAb*_*act 11
我更改了查询以使用以下代替Regex.IsMatch
:
where SqlMethods.Like(cust.Acct, ProductionMask)
Run Code Online (Sandbox Code Playgroud)
哪里 ProductionMask = "[bBgG][0-9][0-9][0-9][0-9]"
等价的RegEx是: ^[B,G]\d{4}$
如果有人发现2个面具不应该产生相同的结果,请告诉我...
特别感谢Roman Khramtsov和db_developer的参考信息,感谢Microsoft:P
适用于Sql Server的RegExpLike扩展
参考链接:
http://www.codeproject.com/Articles/42764/Regular-Expressions-in-MS-SQL-Server-2005-2008
http://msdn.microsoft.com/en-us/library/dd456847. ASPX
步骤1:编译SqlRegularExpressions.cs以生成SqlRegularExpressions.dll
// SqlRegularExpressions.cs
// © Copyright 2009, Roman Khramtsov / Major League - SqlRegularExpressions
using System;
using System.Data.SqlTypes; //SqlChars
using System.Collections; //IEnumerable
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server; //SqlFunctionAttribute
/// <summary>
/// Class that allows to support regular expressions in MS SQL Server 2005/2008
/// </summary>
public partial class SqlRegularExpressions
{
/// <summary>
/// Checks string on match to regular expression
/// </summary>
/// <param name="text">string to check</param>
/// <param name="pattern">regular expression</param>
/// <returns>true - text consists match one at least, false - no matches</returns>
[SqlFunction]
public static bool Like(string text, string pattern, int options)
{
return (Regex.IsMatch(text, pattern, (RegexOptions)options));
}
/// <summary>
/// Gets matches from text using pattern
/// </summary>
/// <param name="text">text to parse</param>
/// <param name="pattern">regular expression pattern</param>
/// <returns>MatchCollection</returns>
[SqlFunction(FillRowMethodName = "FillMatch")]
public static IEnumerable GetMatches(string text, string pattern, int options)
{
return Regex.Matches(text, pattern, (RegexOptions)options);
}
/// <summary>
/// Parses match-object and returns its parameters
/// </summary>
/// <param name="obj">Match-object</param>
/// <param name="index">TThe zero-based starting position in the original string where the captured
/// substring was found</param>
/// <param name="length">The length of the captured substring.</param>
/// <param name="value">The actual substring that was captured by the match.</param>
public static void FillMatch(object obj, out int index, out int length, out SqlChars value)
{
Match match = (Match)obj;
index = match.Index;
length = match.Length;
value = new SqlChars(match.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
步骤2:在数据库上运行DbInstall.sql SQL
sp_configure 'clr enabled', 1
reconfigure
go
--needs full path to DLL
create assembly SqlRegularExpressions
from '..\SqlRegularExpressions.dll'
with PERMISSION_SET = SAFE
go
create function RegExpLike(@Text nvarchar(max), @Pattern nvarchar(255), @Options int = 0)
returns bit
as external name SqlRegularExpressions.SqlRegularExpressions.[Like]
go
create function RegExpMatches(@text nvarchar(max), @pattern nvarchar(255), @Options int = 0)
returns table ([Index] int, [Length] int, [Value] nvarchar(255))
as external name SqlRegularExpressions.SqlRegularExpressions.GetMatches
go
Run Code Online (Sandbox Code Playgroud)
drop function RegExpLike
drop function RegExpMatches
drop assembly SqlRegularExpressions
go
sp_configure 'clr enabled', 0
reconfigure
go
Run Code Online (Sandbox Code Playgroud)
步骤3:在模型图上右键单击,选择"从数据库更新模型...",使用更新向导将存储的函数添加到模型中.
第4步:在实体上下文类中创建导入的函数.
public class TheCompanyContext : Entities
{
// Please check your entity store name
[EdmFunction("TheCompanyDbModel.Store", "RegExpLike")]
public bool RegExpLike(string text, string pattern, int options)
{
throw new NotSupportedException("Direct calls are not supported.");
}
}
Run Code Online (Sandbox Code Playgroud)
第5步:最后,您可以在LINQ to Entities上使用正则表达式:)
User[] qry = (from u in context.Users
where u.ApplicationName == pApplicationName
&& context.RegExpLike(u.Username, usernameToMatch, (int)RegexOptions.IgnoreCase)
orderby u.Username
select u)
.Skip(startIndex)
.Take(pageSize)
.ToArray();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13612 次 |
最近记录: |