2012-04-13 7 views
37

Il seguente codice implementa un UDT che deriva da un generico (SortedDictionary):Perché i tipi di CLR derivati ​​da generici non sono supportati in SQL Server 2008 e versioni successive?

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

Creazione del tipo (T-SQL):

CREATE TYPE dbo.udtMassSpectra EXTERNAL NAME MassSpectra.udtMassSpectra; 

genera un'eccezione:

Messaggio 10331, livello 16, stato 1, riga 1 Digitare 'udtMassSpectra' nell'assieme 'MassSpectra' deriva da un tipo generico che non è supportato per un Tipo CLR.

Qual è il motivo? C'è qualche soluzione alternativa oltre a nascondere la classe base all'interno di un membro privato? Questo codice funziona correttamente su SQL Server 2005.

+1

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

+0

Penso che abbia funzionato nel 2005 e il rapporto non è stato chiuso su Connect indica che potresti esserti imbattuto in un bug vecchio stile. – Godeke

risposta

0

Non ho esperienza con gli UDT, ma forse il problema è che float non è in grado di rappresentare il valore NULL di SQL Server.

ho fatto qualche ricerca e abbiamo trovato questo here

+0

'udtMassSpectra' implementa' bool IsNull' dall'interfaccia ['INullable'] (http://msdn.microsoft.com/en-us/library/system.data.sqltypes.inullable.aspx). Quindi il tipo è in grado di rappresentare il valore Null di SQL Server. Forse dovrei chiarire che questo codice funziona bene su SQL Server 2005 ma non funziona nelle versioni successive del server SQL. – jahu

0

È possibile in modo molto semplice aggirare questa limitazione memorizzando un'istanza di SortedDictionary<float, float> nel vostro UDT.

Solo per curiosità, mi piacerebbe vedere come una classe generica viene creata un'istanza in un contesto di T-SQL, come un tipo di dati di colonna, variabile, ecc

+1

Grazie, ma ho già menzionato questa soluzione alternativa nella mia domanda. Utilizzare il tipo del genere, abbastanza standard penso: 'CREATE TABLE #test ( \t [id] [uniqueidentifier] NOT NULL, \t [spectrum_freetext] [varchar] (max) NULL, \t [spectrum_binary] [dbo]. [udtMassSpectra] NULL, ) ON [PRIMARY] 'o come questo' seleziona udtMassSpectra :: Parse ('669.2344-745.5663 | 801.7557-880.7614 | 889.2369-978.5437 | 1016.6830-12 |'). ToString() come LCMS' – jahu

1

Un altro suggerimento:

verificare che il tipo è stato definito come classe, non è primitivo, annidato o generico

PS:

Per quanto riguarda "ha lavorato su MSSQL 2005 ma non su MSSQL 2008" - cito Tom Petty: "Sei stato fortunato, piccola!" ;)

Problemi correlati