How to simulate regular expressions in LINQ-to-SQL

后端 未结 5 1600
生来不讨喜
生来不讨喜 2020-12-08 12:20

I have a database table with customer account numbers. Within the same table are test accounts that don\'t match the production formatting: say, \'A1111\' is production but

5条回答
  •  情歌与酒
    2020-12-08 12:43

    special thanks to Roman Khramtsov and db_developer for reference information, and thanks to Microsoft :P

    RegExpLike Extension For Sql Server

    Reference links:
    http://www.codeproject.com/Articles/42764/Regular-Expressions-in-MS-SQL-Server-2005-2008
    http://msdn.microsoft.com/en-us/library/dd456847.aspx

    Step1: Compile SqlRegularExpressions.cs to generate 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
    
    /// 
    /// Class that allows to support regular expressions in MS SQL Server 2005/2008
    /// 
    public partial class SqlRegularExpressions
    {
        /// 
        /// Checks string on match to regular expression
        /// 
        /// string to check
        /// regular expression
        /// true - text consists match one at least, false - no matches
        [SqlFunction]
        public static bool Like(string text, string pattern, int options)
        {
            return (Regex.IsMatch(text, pattern, (RegexOptions)options));
        }
    
        /// 
        /// Gets matches from text using pattern
        /// 
        /// text to parse
        /// regular expression pattern
        /// MatchCollection
        [SqlFunction(FillRowMethodName = "FillMatch")]
        public static IEnumerable GetMatches(string text, string pattern, int options)
        {
            return Regex.Matches(text, pattern, (RegexOptions)options);
        }
    
        /// 
        /// Parses match-object and returns its parameters 
        /// 
        /// Match-object
        /// TThe zero-based starting position in the original string where the captured
        ///     substring was found
        /// The length of the captured substring.
        /// The actual substring that was captured by the match.
        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);
        }
    
    }
    

    Step 2: Run DbInstall.sql SQL on the database

    DbInstall.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
    

    DbUninstall.sql

    drop function RegExpLike
    drop function RegExpMatches
    
    drop assembly SqlRegularExpressions
    go
    
    sp_configure 'clr enabled', 0
    reconfigure
    go
    

    Step 3: On model diagram right click, select “Update Model from Database...”, use update wizard to add stored functions to model.
    Model diagram context menu Update wizard Model browser

    Step 4: Create imported functions in entity context class.

    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.");
            }
    }
    

    Step 5: Finally you can use regular expressions on 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();
    

提交回复
热议问题