Importei um banco de dados existente (SQL2012) para um projeto SSDT no VS2017 e ao tentar implantá-lo em minha instância local (SQL2016) recebo a mensagem de erro:
CREATE ASSEMBLY para o assembly 'System.DirectoryServices' falhou porque o assembly 'System.DirectoryServices' falhou na verificação.
Não tenho problemas em criar o Assembly no meu banco de dados no SSMS ao apontá-lo para:
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.DirectoryServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.dll
No meu projeto SSDT eu tenho a estrutura de destino definida como .NET Framework 4 em SQLCLR.
A referência a System.DirectoryServices tem as opções Generate Sql Script e Model Aware definidas como true e permissões definidas como Unsafe.
As configurações do banco de dados também têm a opção confiável habilitada.
A execução select * from sys.dm_clr_properties
na minha instância retorna:
directory C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
version v4.0.30319
state CLR is initialized
O que preciso mudar para que meu projeto seja publicado com sucesso?
Mensagem de erro completa abaixo.
Creating [System.DirectoryServices]...
Warning: The Microsoft .NET Framework assembly 'system.directoryservices, version=4.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a.' you are registering is not fully tested in the SQL Server hosted environment and is not supported. In the future, if you upgrade or service this assembly or the .NET Framework, your CLR integration routine may stop working. Please refer SQL Server Books Online for more details.
(221,1): SQL72014: .Net SqlClient Data Provider: Msg 6218, Level 16, State 2, Line 1 CREATE ASSEMBLY for assembly 'System.DirectoryServices' failed because assembly 'System.DirectoryServices' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database. CLR Verifier error messages if any will follow this message
[ : System.DirectoryServices.ActiveDirectorySecurity::PurgeAccessRules][mdToken=0x6000009][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::PurgeAuditRules][mdToken=0x6000010][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::get_AccessRightType][mdToken=0x6000015][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::get_AccessRuleType][mdToken=0x6000016][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::get_AuditRuleType][mdToken=0x6000017][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::ModifyAccessRule][mdToken=0x6000008][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::ModifyAuditRule][mdToken=0x600000f][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::AccessRuleFactory][mdToken=0x6000011][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::AuditRuleFactory][mdToken=0x6000013][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::AccessRuleFactory][mdToken=0x6000012][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::AuditRuleFactory][mdToken=0x6000014][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::.ctor][mdToken=0x6000001][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurity::AddAccessRule][mdToken=0x6000002][offset 0x00000000] Code size is zero.
[ : System.DirectoryServices.ActiveDirectorySecurit...
(221,0): SQL72045: Script execution error. The executed script:
CREATE ASSEMBLY [System.DirectoryServices]
AUTHORIZATION [dbo]
FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300A1E3A14B0000000000000000E00022200B01080000E801000008000000000000C205020000200000002002000000AC65002000000002000004000000000000000400000000000000006002000002000062580200030040850000100000100000000010000010000000000000100000000000000000000000700502004F000000002002006C040000000000000000000000F2010070170000004002000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000038E601000020000000E8010000020000000000000000000000000000200000602E727372630000006C040000002002000006000000EA0100000000000000000000000000400000402E72656C6F6300000C00000000400200
An error occurred while the batch was being executed.
Não tenho certeza se esse comportamento é pretendido pelo SSDT ou uma alteração de versões anteriores, mas o que está acontecendo é que o "assemblies de referência" está sendo puxado. Os assemblies de referência não são o assembly real e, portanto, não funcionarão para importar para o SQL Server. O que é frustrante aqui é que, mesmo que você use "Procurar" ao adicionar a Referência e selecione C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\System.DirectoryServices.dll e selecione "true"
Model Aware
em suas propriedades, O SSDT ainda puxará o Reference Assembly (a 114 kb) em vez da DLL que você apontou (que tem 413 kb). Mais especificamente, ele puxará o assembly de referência da pasta que corresponde à "Target Framework Version" definida nas propriedades do projeto (por exemplo, 4.6.1 ==C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1 ). Se for importante, estou usando o Visual Studio 2015 e o SSDT para Management Studio 2017 (ou seja, v14).No entanto, embora não seja o ideal, consegui fazer isso funcionar copiando a DLL para uma pasta que não é do sistema. Copiei o System.DirectoryServices.dll completo em C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\ na pasta do meu projeto e adicionei um "item existente" para apontar para a DLL (na pasta do meu projeto) , que tem uma "ação de compilação" de
None
e, em seguida, defina as propriedades de referência como: Owner =dbo
, Permission Set =UNSAFE
e Model Aware =True
. Depois disso funcionou.Se essa DLL tivesse alguma dependência, imagino que precisaria copiá-la para o meu projeto também. Mas não tenho 100% de certeza sobre essa parte.
Acho que podemos adicionar essa experiência à lista de motivos para não usar bibliotecas .NET Framework não suportadas e/ou SSDT ;-)