2012-04-13 6 views
37

El código siguiente implementa un UDT que se deriva de un genérico (SortedDictionary):¿Por qué los tipos CLR derivados de genéricos no son compatibles con SQL Server 2008 y posterior?

[Serializable] 
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined, MaxByteSize = 8000)] 
public class udtMassSpectra : SortedDictionary<float, float>, INullable, IBinarySerialize, ICloneable, IDisposable 
{ 
... 
} 

Creación del tipo (T-SQL):

CREATE TYPE dbo.udtMassSpectra EXTERNAL NAME MassSpectra.udtMassSpectra; 

se emite una excepción:

Msg 10331, nivel 16, estado 1, línea 1 Escriba 'udtMassSpectra' en el ensamblado 'MassSpectra' deriva de un tipo genérico que no es compatible con CLR Tipo.

¿Cuál es el motivo? ¿Hay alguna solución alternativa que no sea ocultar la clase base dentro de un miembro privado? Este código funciona bien en SQL-Server 2005.

+1

Espero que respondan. http://connect.microsoft.com/SQLServer/feedback/details/737635/cannot-create-udt-which-derives-from-a-generic-on-sql-server-2008 – lorond

+0

Creo que el hecho de que funcionó en 2005 y el informe no se ha cerrado. Connect indica que es posible que haya tropezado con un error antiguo. – Godeke

Respuesta

0

No tengo experiencia con UDT, pero tal vez el problema es que float no puede representar el valor NULL de SQL-Server.

me hizo una investigación y encontraron esta here

+0

'udtMassSpectra' implementa' bool IsNull' desde la interfaz ['INullable'] (http://msdn.microsoft.com/en-us/library/system.data.sqltypes.inullable.aspx). Entonces, el tipo puede representar el valor nulo del servidor SQL. Tal vez debería aclarar que este código funciona bien en SQL Server 2005 pero falla en las versiones posteriores de SQL Server. – jahu

0

Puede muy simple evitar esta limitación mediante el almacenamiento de una instancia de SortedDictionary<float, float> en su UDT.

Sólo por curiosidad, me gustaría ver como una clase genérica se instancia en un contexto de T-SQL, como un tipo de datos de columna, variable, etc.

+1

Gracias, pero mencioné esta solución en mi pregunta. Utilice el tipo como este, bastante estándar pienso: CREATE TABLE #test ( \t [id] [uniqueidentifier] NOT NULL, \t [spectrum_freetext] [varchar] (max) NULL, \t [spectrum_binary] [dbo]. [udtMassSpectra] NULL, ) ON [PRIMARY] 'o como este' select udtMassSpectra :: Parse ('669.2344-745.5663 | 801.7557-880.7614 | 889.2369-978.5437 | 1016.6830-12 |'). ToString() como LCMS' – jahu

1

Otra sugerencia:

Compruebe que el tipo se definió como una clase, no es primitivo, anidado o genérico

PS:

En cuanto a "trabajó en MSSQL 2005 pero no en MSSQL 2008", cito a Tom Petty: "¡Tuviste suerte, cariño!" ;)

Cuestiones relacionadas