我有一个SQLCLR函数,它将一个对象序列化为XML,在我的本地开发机器(以及我们的其他DBA的机器)上工作正常,但是当我尝试在我们的测试数据库服务器上运行相同的函数时,我得到了以下内容:
Ms 6522,Level 16,State 1,Line 1
在执行用户定义的例程或聚合“GetXml”期间发生.NET Framework错误:
System.InvalidOperationException:无法加载动态生成的序列化程序集。在某些托管环境中,组件加载功能受到限制,请考虑使用预生成的序列化程序。 有关详细信息,请参阅内部异常。System.IO.FileLoadException:主机已禁用LoadFrom(),LoadFile(),Load(byte [])和LoadModule()。 System.IO.FileLoadException:
at System.Reflection.RuntimeAssembly.nLoadImage(Byte [] rawAssembly,Byte [] rawSymbolStore,Evidence evidence,StackCrawlMark& stackMark,Boolean fIntrospection,SecurityContextSource securityContextSource)
在System.Reflection.Assembly.Load(Byte [] rawAssembly,Byte [] rawSymbolStore,Evidence securityEvidence)
在Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters选项,String [] fileNames)
在Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options,String [] sources) 在Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options,String [] sources) 在System.Xml.Serialization.Compiler.Compile(Assembly parent,String ns,XmlSerializerCompilerParameters xmlParameters,Evidence evidence) System.InvalidOperationException: 在System.Xml.Serialization.Compiler.Compile(Assembly parent,String ns,XmlSerializerCompilerParameters xmlParameters,Evidence evidence) 在System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping [] xmlMappings,Type [] types,String defaultNamespace,Evidence evidence,XmlSerializerCompilerParameters parameters,Assembly assembly,Hashtable assemblies) 在System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping,Type type,String defaultNamespace) 在System.Xml.Serialization.XmlSerializer..ctor(Type type,String defaultNamespace) 在XmlExtensions.ToXml [T](T值) 在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在其他开发人员的机器上运行良好,但在我们的测试服务器上出于同样的原因失败了。我没有发现任何告诉我为什么这会在某些机器上运行而在其他机器上运行的情况。
答案 0 :(得分:1)
我还在我的笔记本电脑上测试了这个相同的代码并且无法将其弄错。所以这就是我们所知道的:
确实可以:
它无效:
鉴于你的开发机器,DBA的本地机器和我的本地机器都工作,但服务器没有,这可能是服务器没有安装正确的.NET Framework更新的问题。
检查测试服务器是否已使用更新的.NET Frameworks 4.0及更高版本进行了修补。显然它有安装SQL Server 2012时安装的4.0,如果它还没有安装,但我的机器有4.5,4.5.2,现在有4.6。检查4.x系列中的计算机,DBA和测试服务器.NET Framework。
P.S。如果您未通过SELECT
执行SqlConnection
,请不要在DataAccess = DataAccessKind.Read
属性中设置SqlFunction
。除非您实际从SQL Server读取数据,否则这是您不想要的性能损失。默认值为DataAccessKind.None
。
来自O.P。
的更新我们的测试服务器上只有.NET 4.0,而我们的机器只有4.6。当我更新.NET框架时,问题就消失了。