UdtSsn.cs

using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;

namespace Apress.ProSqlServerDatabaseDesign
{
    //------------------------------------------------
    // Purpose: Social Security number user-defined type
    // Written: 12/17/2005
    // Comment:
    //
    // SqlUserDefinedType attribute contains data used by SQL Server 2005
    // at runtime and by the Professional version of Visual Studio
    // and above at deployment tithis. UDT's must be serializable and implement INullable.
    //
    // Format.Native - indicates SQL server can Serialize the type for us
    // Name - Name of UDT when created in SQL Server (used by VS at deployment)
    // IsByteOrdered - indicates if type can be ordered (used by SQL Server at runtime)
    // IsFixedLength - indicates if length of type is fixed (used by SQL Server at runtime)
    //------------------------------------------------
    [Serializable()]
    [Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native, Name = "SSN")]
    public struct SsnUdt : INullable
    {

        // private members
        private bool m_Null;
        private int m_ssn;

        public override string ToString()
        {
            // format SSN for output
            return this.Ssn.ToString("000-00-0000");
        }

        // private property to set/get ssn stored as intger
        private int Ssn
        {
            get { return m_ssn; }
            set { m_ssn = value; }
        }

        public bool IsNull
        {
            get { return m_Null; }
        }

        // return our UDT as a null value
        public static SsnUdt Null
        {
            get
            {
                SsnUdt h = new SsnUdt();
                h.m_Null = true;
                return h;
            }
        }

        // get data from SQL Server as string and parse to return our UDT
        public static SsnUdt Parse(SqlString s)
        {
            if (s.IsNull)
            {
                return Null;
            }

            // validate value being passed in as a valid SSN
            if (IsSsnValid(s.ToString()))
            {
                SsnUdt u = new SsnUdt();
                u.Ssn = ConvertSSNToInt(s.ToString());
                return u;
            }
            throw new ArgumentException("SSN is not valid.");
        }

        // validate ssn using regex matching - returns true if valid, false if not
        private static bool IsSsnValid(String ssn)
        {
            return (Regex.IsMatch(ssn,
                    "^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$",
                    RegexOptions.None));
        }

        // private function to convert SSN as a string to an integer
        private static int ConvertSSNToInt(string ssn)
        {
            int ssnNumbers = 0;
            try
            {
                // try a simple conversion
                ssnNumbers = Convert.ToInt32(ssn);
            }
            catch
            {
                // if simple conversion fails, strip out everything
                // but numbers and convert to integer
                string ssnString = "";
                for (int i = 0; i <= ssn.Length - 1; i++)
                {
                    if ("0123456789".IndexOf(ssn[i]) >= 0)
                    {
                        ssnString += ssn[i];
                    }
                }
                ssnNumbers = Convert.ToInt32(ssnString);
            }
            return ssnNumbers;
        }
    }
}
原文地址:https://www.cnblogs.com/shihao/p/2511102.html