将 VB CLR 函数转换为 C#
Convert VB CLR function to 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 through 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.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 is similar to ternary operators。在此基础上,我尝试了以下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);
}
该函数正在使用正则表达式选项的位域构建一个 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#)。
but as soon as I brought it into our SSDT project to incorporate into our next .dacpac release, nothing worked!
这与编写它的初始语言有什么关系? DLL 使用相同的字节码,即使它最初是用 C# 编写的,对吧?您使用的 SQL 服务器是什么版本?这很可能是安全问题,而不是语言问题。
另外,你带入SSDT项目的“it”是什么?原始代码或程序集,因为它已经加载到 SQL 服务器?这可能是 SSDT 配置问题。
在任何一种情况下,如果您在使用 VB.NET 代码时收到错误,请先 post 检查这些错误并确认问题确实是语言问题,而不是它可能出现的许多其他问题是。你可能白白做了很多额外的工作,而这一切都是基于一个错误的假设。假设您确实收到消息编号 and/or 文本的错误,您是否查看了其中任何一个?再次请 post 回答问题,因为即使使用有效的 C# 代码,你也很可能 运行 再次遇到同样的问题。
另外,如果你想要 RegEx 函数,只需安装 SQL# (SQLsharp) 库(我写的)就可以了。免费版包含大部分 RegEx 函数,它们相当完整地表示了您可以在 .NET 中使用 RegEx 执行的操作(包括传入 RegExOptions):Match、Matches、Split、Replace、CaptureGroups、CaptureGroupCaptures 等
我找到了一种无需转换为 C# 即可使用 VB 脚本的方法
项目属性 > SQL CLR > 语言
完成后,所有标记为 CLR 的项目都可以使用 VB flavor:
SSDT DB 项目似乎可以使用 C# CLR 或 VB CLR,但不能同时使用两者(即使在 SQL 服务器中两者都可以)。
如何将下面的 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 through 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.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 is similar to ternary operators。在此基础上,我尝试了以下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);
}
该函数正在使用正则表达式选项的位域构建一个 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#)。
but as soon as I brought it into our SSDT project to incorporate into our next .dacpac release, nothing worked!
这与编写它的初始语言有什么关系? DLL 使用相同的字节码,即使它最初是用 C# 编写的,对吧?您使用的 SQL 服务器是什么版本?这很可能是安全问题,而不是语言问题。
另外,你带入SSDT项目的“it”是什么?原始代码或程序集,因为它已经加载到 SQL 服务器?这可能是 SSDT 配置问题。
在任何一种情况下,如果您在使用 VB.NET 代码时收到错误,请先 post 检查这些错误并确认问题确实是语言问题,而不是它可能出现的许多其他问题是。你可能白白做了很多额外的工作,而这一切都是基于一个错误的假设。假设您确实收到消息编号 and/or 文本的错误,您是否查看了其中任何一个?再次请 post 回答问题,因为即使使用有效的 C# 代码,你也很可能 运行 再次遇到同样的问题。
另外,如果你想要 RegEx 函数,只需安装 SQL# (SQLsharp) 库(我写的)就可以了。免费版包含大部分 RegEx 函数,它们相当完整地表示了您可以在 .NET 中使用 RegEx 执行的操作(包括传入 RegExOptions):Match、Matches、Split、Replace、CaptureGroups、CaptureGroupCaptures 等
我找到了一种无需转换为 C# 即可使用 VB 脚本的方法
项目属性 > SQL CLR > 语言
完成后,所有标记为 CLR 的项目都可以使用 VB flavor:
SSDT DB 项目似乎可以使用 C# CLR 或 VB CLR,但不能同时使用两者(即使在 SQL 服务器中两者都可以)。