簡體   English   中英

將VB CLR function轉換為C#

[英]Convert VB CLR function to C#

How can I convert below VB.net SQL CLR function to C# CLR Function for a VS SSDT SQL Project?

我需要將其轉換為 C# 因為似乎內置 SSDT 項目對 CLR 功能的支持僅是 C# 如果我能找到一種以與 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)

我試圖通過Telerik C# Converter運行Class

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.IgnoreCase, RegexOptions.None) | Interaction.IIf(MultiLine.Value, RegexOptions.Multiline, RegexOptions.None) | Interaction.IIf(ExplicitCapture.Value, RegexOptions.ExplicitCapture, RegexOptions.None) | Interaction.IIf(Compiled.Value, RegexOptions.Compiled, RegexOptions.None) | Interaction.IIf(SingleLine.Value, RegexOptions.Singleline, RegexOptions.None) | Interaction.IIf(IgnorePatternWhitespace.Value, RegexOptions.IgnorePatternWhitespace, RegexOptions.None) | Interaction.IIf(RightToLeft.Value, RegexOptions.RightToLeft, RegexOptions.None) | Interaction.IIf(ECMAScript.Value, RegexOptions.ECMAScript, RegexOptions.None) | Interaction.IIf(CultureInvariant.Value, RegexOptions.CultureInvariant, RegexOptions.None));
            return (Result);
        }
}

Class 中的所有其他功能似乎都可以使用 Telerik 轉換器進行轉換。 我試着四處尋找這個,似乎IIf 類似於三元運算符 在此基礎上,我嘗試了以下 2 個示例,但沒有任何效果...

嘗試 1

[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 = 
            (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, 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 = Iif(IgnoreCase.Value, RegexOptions.IgnoreCase, RegexOptions.None) || Iif(MultiLine.Value, RegexOptions.Multiline, RegexOptions.None) || Iif(ExplicitCapture.Value, RegexOptions.ExplicitCapture, RegexOptions.None) || Iif(Compiled.Value, RegexOptions.Compiled, RegexOptions.None) || Iif(SingleLine.Value, RegexOptions.Singleline, RegexOptions.None) || Iif(IgnorePatternWhitespace.Value, RegexOptions.IgnorePatternWhitespace, RegexOptions.None) || Iif(RightToLeft.Value, RegexOptions.RightToLeft, RegexOptions.None) || Iif(ECMAScript.Value, RegexOptions.ECMAScript, RegexOptions.None) || Iif(CultureInvariant.Value, RegexOptions.CultureInvariant, RegexOptions.None);
        return (Result);
    }

function 正在使用正則表達式選項的位域構建一個 int(它們的設計方式可以將它們組合在一起)。 所以我會寫一個實用程序 function 並這樣做: -

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

盡管鏈接文檔頁面上的措辭確實具有誤導性,但 state 並不支持 VB.NET。 您是否嘗試過創建 VB.NET 項目? 什么是關於出版的“破碎”? 我不使用 VB.NET 所以我沒有嘗試過,但在過去的 16 年中我也沒有聽到/看到有人提出過這種說法(自從引入了 SQLCLR 並且人們主要使用 C#,但也絕對是 ZBD5C5ZF6AFE53C84 ,並且在較小程度上是 Visual C++,有時,並且並非沒有一些痛苦,F#)。

但是,當我將它帶入我們的 SSDT 項目並合並到我們的 next.dacpac 版本中時,沒有任何效果!

這與它最初使用的語言有什么關系? DLL 的字節碼與最初用 C# 編寫的字節碼相同,對吧? 您使用的是什么版本的 SQL 服務器? 這很可能是安全問題,而不是語言問題。

另外,您帶入 SSDT 項目的“它”是什么? 原始代碼還是程序集,因為它已經加載到 SQL 服務器中? 這可能是 SSDT 配置問題。

在任何一種情況下,如果您在使用 VB.NET 代碼時收到錯誤,請首先發布這些錯誤並確認問題確實是語言而不是許多其他問題。 你可能會白白做很多額外的工作,所有這些都是基於一個錯誤的假設。 假設您確實收到消息編號和/或文本錯誤,您是否查看了其中任何一個? 同樣,請將這些發布到問題中,因為即使使用 C# 代碼,您也很可能再次遇到同樣的問題。

另外,只是把它放在那里,如果你想要 RegEx 函數,你可以通過安裝SQL# (SQLsharp)庫(我寫的)來完成。 免費版包含大部分 RegEx 函數,它們相當完整地表示了您可以在 .NET 中使用 RegEx 執行的操作(包括傳入 RegExOptions):Match、Matches、Split、Replace、CaptureGroups、CaptureGroupCaptures 等。

我找到了一種無需轉換為 C# 即可使用 VB 腳本的方法

項目屬性 > SQL CLR > 語言

項目 SQLCLR 屬性

一旦完成,所有標記為 CLR 的項目都可以使用 VB 風格獲得:

在此處輸入圖像描述

似乎 SSDT DB 項目可以使用 C# CLR 或 VB CLR 但不能同時使用兩者(即使兩者都可以在 SQL 服務器中使用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM