消息 6522 "Cannot load dynamically generated serialization assembly" 正在执行 XML 序列化

Msg 6522 "Cannot load dynamically generated serialization assembly" doing XML Serialization

我有一个 SQLCLR 函数将一个对象序列化为 XML,它在我的本地开发机器(以及我们其他 DBA 的机器)上运行良好,但是当我尝试 运行 在我们的测试数据库服务器上使用相同的函数,我得到以下信息:

Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "GetXml":
System.InvalidOperationException: Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer. Please see inner exception for more information.

System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.
System.IO.FileLoadException:
at System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
at System.Reflection.Assembly.Load(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence securityEvidence)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources) at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources) at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence) System.InvalidOperationException: at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence) at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace) at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace) at XmlExtensions.ToXml[T](T value) at UserDefinedFunctions.GetXml()

我看到很多帖子说你需要创建一个 Assembly.XmlSerializers.dll,但如果真的是这样,为什么它在我们本地机器上运行良好而不需要那个 DLL?

为了确保它与编译相同代码无关,我创建了一个新的 SQL 项目,编译它,然后将 SQL 脚本发送给我们的 DBA而且他能够 运行 它而不需要 XmlSerializers.dll.

using System;
using System.Data.SqlTypes;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.SqlServer.Server;

public class UserDefinedFunctions
{
    [SqlFunction(IsDeterministic = true, DataAccess = DataAccessKind.Read)]
    public static SqlXml GetXml()
    {
        var x = new Test1 { S = DateTime.Now.ToString() };
        return new SqlXml(new XmlTextReader(x.ToXml(), XmlNodeType.Document, null));
    }
}

public class Test1
{
    public string S { get; set; }
}

public static class XmlExtensions
{
    public static string ToXml<T>(this T value)
    {
        if (value == null) return string.Empty;

        var xmlserializer = new XmlSerializer(typeof(T));

        using (StringWriter stringWriter = new StringWriter())
        {
            using (var writer = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
            {
                xmlserializer.Serialize(writer, value);
                return stringWriter.ToString();
            }
        }
    }
}

此项目的 dacpac 在其他开发人员的机器上加载正常,但在我们的测试服务器上由于同样的原因而失败。我还没有找到任何东西告诉我为什么这会在某些机器上工作而不在其他机器上工作。

我也在我的笔记本电脑上测试了同样的代码,没有出错。所以这就是我们所知道的:

它确实适用于:

  • Dev 的本地机器运行SQLServer 2012 SP3.
  • DBA的本地机器运行SQLServer 2012 SP3.
  • 我的笔记本电脑 运行 SQL Server 2012 SP 2(LocalDB 和开发版)和 SQL Server 2014 SP 1 (LocalDB)。

它不适用于:

  • 测试服务器 运行 SQL Server 2012 SP3。

鉴于你的开发机器、DBA 的本地机器和我的本地机器都可以工作,但服务器没有,这可能是服务器没有安装正确的 .NET Framework 更新的问题。

检查测试服务器是否已使用最新的 .NET Frameworks 4.0 及更新版本进行修补。显然它有 4.0,因为如果它还没有安装 SQL Server 2012 时会安装,但我的机器有 4.5、4.5.2,现在有 4.6。检查您的计算机、DBA 和 4.x 系列中的测试服务器 .NET Framework。

P.S。如果您没有通过 SqlConnection 执行 SELECT,则不要在 SqlFunction 属性中设置 DataAccess = DataAccessKind.Read。除非您实际上是从 SQL 服务器读取数据,否则这是您不希望的性能损失。默认为 DataAccessKind.None.

来自 O.P 的更新。

Our test servers only had .NET 4.0 on them vs 4.6 on our machines. When I updated the .NET framework, the problem went away.