微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将 VB CLR 函数转换为 C#

如何解决将 VB CLR 函数转换为 C#

如何将下面的 VB.net sql CLR 函数转换为 VS SSDT sql 项目的 C# CLR 函数

我需要将其转换为 C#,因为 built-in SSDT Project support for CLR functions is C# only?如果我能找到一种以与 VS SSDT 项目兼容的方式使用原始 VB 并且不会破坏发布工作流程的方法,那么我会接受这个答案!我发现使用 SSMS 中的 T-sql 命令将 .dll 编译到 sql 服务器中真的很容易……但是当我将它引入我们的 SSDT 项目以合并到我们的下一个 .dacpac 版本时,没有任何效果

sqlFunction(IsDeterministic:=True,IsPrecise:=True)> _
Public Shared Function RegExOptionEnumeration(ByVal IgnoreCase As sqlBoolean,_
             ByVal MultiLine As sqlBoolean,_
                           ByVal ExplicitCapture As sqlBoolean,_
                           ByVal Compiled As sqlBoolean,_
                           ByVal SingleLine As sqlBoolean,_
                           ByVal IgnorePatternWhitespace As sqlBoolean,_
                           ByVal RightToLeft As sqlBoolean,_
                           ByVal ECMAScript As sqlBoolean,_
                           ByVal CultureInvariant As sqlBoolean) _
              As sqlInt32
  Dim Result As Integer
  Result = (IIf(IgnoreCase.Value,RegexOptions.IgnoreCase,RegexOptions.None) Or _
   IIf(MultiLine.Value,RegexOptions.Multiline,RegexOptions.None) Or _
   IIf(ExplicitCapture.Value,RegexOptions.ExplicitCapture,_
                RegexOptions.None) Or _
   IIf(Compiled.Value,RegexOptions.Compiled,RegexOptions.None) Or _
   IIf(SingleLine.Value,RegexOptions.Singleline,RegexOptions.None) Or _
   IIf(IgnorePatternWhitespace.Value,RegexOptions.IgnorePatternWhitespace,_
                RegexOptions.None) Or _
   IIf(RightToLeft.Value,RegexOptions.RightToLeft,RegexOptions.None) Or _
   IIf(ECMAScript.Value,RegexOptions.ECMAScript,RegexOptions.None) Or _
   IIf(CultureInvariant.Value,RegexOptions.CultureInvariant,RegexOptions.None))
  Return (Result)

我试图通过 Class 运行 Telerik C# Converter

Telerik 在 C# 下生成

public class RegularExpressionFunctions
    {
        // 
        // RegExOptions function
        // this is used simply to create the bitmap that is passed to the varIoUs 
        // CLR routines

        [sqlFunction(IsDeterministic = true,IsPrecise = true)]
        public static sqlInt32 RegExOptionEnumeration(sqlBoolean IgnoreCase,sqlBoolean MultiLine,sqlBoolean ExplicitCapture,sqlBoolean Compiled,sqlBoolean SingleLine,sqlBoolean IgnorePatternWhitespace,sqlBoolean RightToLeft,sqlBoolean ECMAScript,sqlBoolean CultureInvariant)
        {
            int Result;
            Result = (Interaction.IIf(IgnoreCase.Value,RegexOptions.None) | Interaction.IIf(MultiLine.Value,RegexOptions.None) | Interaction.IIf(ExplicitCapture.Value,RegexOptions.None) | Interaction.IIf(Compiled.Value,RegexOptions.None) | Interaction.IIf(SingleLine.Value,RegexOptions.None) | Interaction.IIf(IgnorePatternWhitespace.Value,RegexOptions.None) | Interaction.IIf(RightToLeft.Value,RegexOptions.None) | Interaction.IIf(ECMAScript.Value,RegexOptions.None) | Interaction.IIf(CultureInvariant.Value,RegexOptions.None));
            return (Result);
        }
}

该类中的所有其他函数似乎都可以通过 Telerik 转换器进行转换。 我试着四处寻找这个,似乎IIf is similar to ternary operators。在此基础上,我尝试了以下两个示例,但没有任何效果...

尝试 1

[sqlFunction(IsDeterministic = true,IsPrecise = true)]
    public static sqlInt32 RegExOptionEnumeration(sqlBoolean IgnoreCase,sqlBoolean CultureInvariant)
    {
        int Result;
        Result = 
            (IgnoreCase.Value == true ? RegexOptions.IgnoreCase : RegexOptions.None) ||
            (MultiLine.Value ? RegexOptions.Multiline : RegexOptions.None) ||
            (ExplicitCapture.Value ? RegexOptions.ExplicitCapture : RegexOptions.None) || 
            (Compiled.Value ? RegexOptions.Compiled : RegexOptions.None) || 
            (SingleLine.Value ? RegexOptions.Singleline : RegexOptions.None) || 
            (IgnorePatternWhitespace.Value ? RegexOptions.IgnorePatternWhitespace : RegexOptions.None) || 
            (RightToLeft.Value ? RegexOptions.RightToLeft : RegexOptions.None) || 
            (ECMAScript.Value ? RegexOptions.ECMAScript : RegexOptions.None) || 
            (CultureInvariant.Value ? RegexOptions.CultureInvariant : RegexOptions.None);
        return (Result);
    }

尝试 2

public static object Iif(bool cond,object left,object right)
    {
        return cond ? left : right;
    }

    [sqlFunction(IsDeterministic = true,sqlBoolean CultureInvariant)
    {
        int Result;
        Result = Iif(IgnoreCase.Value,RegexOptions.None) || Iif(MultiLine.Value,RegexOptions.None) || Iif(ExplicitCapture.Value,RegexOptions.None) || Iif(Compiled.Value,RegexOptions.None) || Iif(SingleLine.Value,RegexOptions.None) || Iif(IgnorePatternWhitespace.Value,RegexOptions.None) || Iif(RightToLeft.Value,RegexOptions.None) || Iif(ECMAScript.Value,RegexOptions.None) || Iif(CultureInvariant.Value,RegexOptions.None);
        return (Result);
    }

解决方法

该函数正在使用正则表达式选项的位域构建一个 int(它们的设计方式可以将它们组合在一起)。所以我会写一个实用程序函数,然后像:-

    static int BitIf(SqlBoolean condition,RegexOptions flag) => condition.Value ? (int) flag : 0;

    static SqlInt32 RegExOptionEnumeration(SqlBoolean IgnoreCase,SqlBoolean MultiLine,SqlBoolean ExplicitCapture,SqlBoolean Compiled,SqlBoolean SingleLine,SqlBoolean IgnorePatternWhitespace,SqlBoolean RightToLeft,SqlBoolean ECMAScript,SqlBoolean CultureInvariant)
    {
            return BitIf(IgnoreCase,RegexOptions.IgnoreCase)
            | BitIf(MultiLine,RegexOptions.Multiline)
            | BitIf(ExplicitCapture,RegexOptions.ExplicitCapture)
            | BitIf(Compiled,RegexOptions.Compiled)
            | BitIf(SingleLine,RegexOptions.Singleline)
            | BitIf(IgnorePatternWhitespace,RegexOptions.IgnorePatternWhitespace)
            | BitIf(RightToLeft,RegexOptions.RightToLeft)
            | BitIf(ECMAScript,RegexOptions.ECMAScript)
            | BitIf(CultureInvariant,RegexOptions.CultureInvariant);
    }
}
,

虽然链接文档页面上的措辞确实具有误导性,但并未说明不支持 VB.NET。您是否尝试过创建 VB.NET 项目?什么是“破”的出版?我不使用 VB.NET,所以我还没有尝试过,但在过去的 16 年里,我也没有听说/看到任何人提出过这种说法(因为引入了 SQLCLR 并且人们主要使用 C#,但肯定是 VB.NET,在较小程度上是 Visual C++,有时也不是没有痛苦,F#)。

但是当我将它引入我们的 SSDT 项目以合并到我们的下一个 .dacpac 版本时,没有任何效果!

这与它最初使用的语言有什么关系? DLL 的字节码与最初用 C# 编写的字节码相同,对吗?您使用的是什么版本的 SQL Server?这很可能是安全问题,而不是语言问题。

另外,您为 SSDT 项目带来的“它”是什么?原始代码还是程序集,因为它已经加载到 SQL Server 中?这可能是 SSDT 配置问题。

在任何一种情况下,如果您在使用 VB.NET 代码时收到错误,请首先发布这些错误并确认问题确实是语言而不是许多其他可能的问题。你可能会白白做很多额外的工作,所有这些都是基于一个错误的假设。假设您确实收到了消息编号和/或文本的错误,您是否查看了其中的任何一个?同样,请将这些问题发布到问题中,因为即使使用 C# 代码,您也很可能再次遇到同样的问题。

另外,只是为了把它放在那里,如果你想要 RegEx 函数,你可以通过安装 SQL# (SQLsharp) 库(我写的)来完成。免费版本包含大多数 RegEx 函数,它们是您在 .NET 中可以使用 RegEx 执行的操作的相当完整的表示(包括传入 RegExOptions):Match、Matches、Split、Replace、CaptureGroups、CaptureGroupCaptures 等。

,

我找到了一种无需转换为 C# 即可使用 VB 脚本的方法

项目属性 > SQL CLR > 语言

Project SQLCLR Properties

一旦完成,所有标记为 CLR 的项目都可以使用 VB 风格获得:

enter image description here

似乎 SSDT DB 项目可以使用 C# CLR 或 VB CLR,但不能同时使用(即使在 SQL Server 中都可以使用)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。