托管 UDT 使您能够扩展 SQL Server 的类型系统
2007-11-11 04:48:09 来源:WEB开发网支持的转换
UDT 必须支持到字符串的转换以及来自字符串的转换。为此,类需要在其接口中定义两个公共方法。第一个是静态方法 Parse,允许将字符串值转换为 UDT 实例。以下是该函数的定义:
// C#public static MyClass Parse(SqlString s)' Visual Basic .NETPublic Shared Function Parse(ByVal s As SqlString) As MyClass
第二个方法是实例方法 ToString 的重写方法,如下所示:
// C#public override string ToString()' Visual Basic .NETPublic Overrides Function ToString() As String
该方法使 UDT 转换为字符串值。虽然并非强制,不过这两种方法的正确实现应该是互逆的。也就是说,这两种方法应该能够使用 Parse 将字符串转换为 UDT,然后用 ToString 方法将其转换回原始的字符串值。
其他要求
除了我之前提到的功能之外,您应该知道还有几个其他的要求。由于类需要有一个构造函数,因此需要在 UDT 中实现它。UDT 类需要一个零参数公共构造函数,如下所示:
// C#public MyClass () { }
另外,可以创建其他的公共构造函数。这是类型的公共成员能够被重载的唯一时机。下面是在创建 UDT 时您应该知道的一些其他限制:
? | 在 .NET 代码中不允许有可更改的静态数据成员。 |
? | 不支持固定长度字符串以及固定长度二进制数据类型。 |
? | 所有类名、方法名和属性名必须与 Yukon sysname 系统数据类型相一致,亦即您的公共名称不能超过 128 个字符。 |
? | 不支持继承;Yukon 不能使用继承,尽管继承依然能够存在于 .NET 代码中。 |
注意,SQL 类型系统不会意识到 UDT 之间的继承层次结构。不过,UDT 的设计者能够用构造类的方式将继承当作一种实现机制。不能从 T-SQL 调用继承的方法,尽管您可以在类型的托管实现中调用这样的方法。
同样,如果您的确创建了一个重载方法,您应该预先警惕。当您在 sql server(WINDOWS平台上强大的数据库平台) 中注册程序集或者创建类型时,它将不会被捕获。这是因为重载方法的检测发生在运行时而非类型创建之时。因此,只要不被调用,重载方法就能够存在于类中。如果该类被调用,将引发一个错误,错误提示为:“More than one method, property, or field was found with name method_name in class class_name in assembly assembly_name.”(在程序集 assembly_name 的类 class_name 中,找到不止一个方法、属性或字段的名称为 method_name。)不支持重载方法、属性或字段。同样,请注意这一规则有个例外,正如我在论及构造函数时所述。
当您需要将方法标记为确定性方法或者允许方法为更改方法时,需要用到 SqlMethod 属性。该属性有四个参数:
Deterministic 表示方法是确定性的 (true) 或者是非确定性的 (false) 。默认情况下为 false。
OnNullCall 如果 OnNullCall 为 false,当至少有一个输入参数为 NULL 时,不对方法求值就返回 NULL。如果 OnNullCall 为 true(这是默认值),不论输入什么参数,将通过对方法求值来确定结果值。
IsMutator 这一属性(默认时为 false)用以说明一个方法是否可以为实例的更改方法。默认时,方法调用不能更改实例的状态。如果创建了一个需要改变实例状态的属性,那么需要使用这一属性将其标记为更改方法。请注意,属性默认情况下为更改方法,并且不需要使用该属性。
DataAccess 该属性表明一个函数或方法是否包含有 SQL SELECT 语句。它能被设置为 DataAccessKind.None 或者 DataAccessKind.Read。
让我们回顾一下基于 CLR 的 UDT 实现的两个示例。第一个例子是一个简单的 Point 类,如图 4 所示。该类型有两个属性 X 和 Y,以及一个公共方法 DistanceTo,用以返回当前 Point 到另一个作为参数传入的 Point 的距离。您将在本文的后面了解它在 Yukon 中的用法。注意,这也能很容易地定义为结构。
第二个例子是一个 Address 类(参见图 5),存储地址、城市、州以及邮政编码数据。该类通过实现 IBinarySerialize 以及 Write 和 Read 方法演示了 UserDefined 的序列化格式。
更多精彩
赞助商链接