|
我使用的是SQL Server 2005 Service Pack2(SP2)(v9.0.3042)那里发布的解决方案对我没有影响。我试着用两个连接字符串。我的一个代码被注释了。
/ }2 R2 c. g. I. G我意识到我可以将所有结果存储在内存中List或ArrayList中间,然后返回。我已经成功地做到了,但这不是这里的目标。目标是在结果可用的时流传输。
; p7 b D$ i8 F: W ~* Y! B使用我的SQL Server版本可以吗?
2 R6 K/ ^) ^) n/ ^这是我的代码:(请注意,当前实际上并没有使用这些参数。我这样做是为了进行调试)+ ?6 T6 j& e0 `- N
public static class StoredProcs{ [SqlFunction( DataAccess = DataAccessKind.Read, SystemDataAccess=SystemDataAccessKind.Read, FillRowMethodName="FillBaseline", TableDefinition = "[baseline_id] [int],[baseline_name] [nvarchar](256),[description] [nvarchar](max),[locked] [bit]" )public static IEnumerable fnGetBaselineByID(SqlString projectName,SqlInt32 baselineID) string connStr = "context connection=true"; string connStr = "data source=.;initial catalog=DBName;integrated security=SSPI;enlist=false"; using (SqlConnection conn = new SqlConnection(connStr)) conn.Open(); using (SqlCommand cmd = new SqlCommand(String.Format(@" SELECT * FROM [DBName].[dbo].[Baseline] WITH (NOLOCK) "),conn)) using (SqlDataReader reader = cmd.ExecuteReader()) while (reader.Read()) yield return new Baseline(reader); ; ;public static void FillBaseline(Object obj,out SqlInt32 id,out SqlString name,out SqlString description,out bool locked) Baseline baseline = (Baseline)obj; id = baseline.mID; name = baseline.nName; description = baseline.mDescription; locked = baseline.mLocked; 这是我的SQL部署脚本的一部分:1 z, Z* t: W& e7 N, {! C
CREATE ASSEMBLY [MyService_Stored_Procs]FROM 'C:\temp\assemblyName.dll'WITH PERMISSION_SET = SAFE当我使用连接字符串时, context connection = true这个错误发生在时:1 | ?- L U+ q4 f5 d' [' z9 F ~
从用户定义的表值函数中获取新行时出现错误:System.InvalidOperationException:数据访问不在上下文中访问。上下文是无用的DataAccessKind.Read或SystemDataAccessKind.Read标记的函数或方法来自表值函数FillRow获取数据回调的方法,还是UDT验证方法。% Y7 D+ _: O; n5 S9 D1 \0 l. ~
当我使用其他连接字符串时,出现了这个错误:
9 D+ t* |$ o, \* b6 i从用户定义的表值函数中获取新行时出现错误:System.Security.SecurityException:请求类型为’System.Data.SqlClient.SqlClientPermission,System.Data,Version/ |6 U8 ^/ U- |( {" E
= 2.0.0.0,Culture = neutral,PublicKeyToken的权限= b77a5c561934e089’失败。6 z) H8 _7 Z4 @# h' {6 n9 k X3 b
( j, o) M) T5 S Z, ]# \) R
解决方案:
& G! S8 O) y$ }' t" ]! X3 X+ y 经过进一步的研究和反复的实验,我找到了解决方案。我在这里提到的文章$ A+ t9 g$ X4 a5 |
您的程序集必须使用Permission_set = external_access创建% Q& y1 }- l0 N& I. R7 B
说起来容易做起来难,但这是一个很好的起点。只需用银行代替它。permission_set = safe会出错:5 o5 ] h0 g: V( d* l& J
assemblyName”创建组件失败,因 assemblyName”未获得PERMISSION_SET =+ {+ [+ g% f) U1 G# U5 L
EXTERNAL_ACCESS授权。如果满足以下任何条件,则授权程序集:数据库所有者(DBO)具有EXTERNAL ACCESS \/ L, L, I# Z; J
ASSEMBLY数据库有权限TRUSTWORTHY数据库属性。或者使用相应的登录名称EXTERNAL ACCESS* [/ p6 U0 h7 v+ [& p6 F: t
ASSEMBLY相应的权限证书或非对称密钥签署程序集。
* ~& C0 f! ~6 h( p1 k因此,我要做的第一件事是对我的dll签署文件。为此,请在这里Visual Studio# G' O! G8 F0 ~6 F/ b# G R$ r
2010年将签名选项卡转入项目属性,然后选择签名程序集并命名。对于这个例子,名字是MyDllKey。我选择不使用密码来保护它。当然,我会dll复制文件sql0 h, v( R+ E3 `2 a5 d! J% F' v
server:C:\ Temp
/ `0 G. M5 N, O- l; X, l以此页面为参考,基于上述键创建了以下三个命令SQL登录名:
$ y2 ^3 o- c$ ?6 u; fCREATE ASYMMETRIC KEY MyDllKey FROM EXECUTABLE FILE = 'C:\Temp\MyDll.dll'CREATE LOGIN MyDllLogin FROM ASYMMETRIC KEY MyDllKeyGRANT EXTERNAL ACCESS ASSEMBLY TO MyDllLogin创建登录名后,我现在可以使用以下命令来创建程序集:0 C5 q3 s$ M) B7 |8 d% _/ k* X# ~7 J
CREATE ASSEMBLY [MyDll]FROM 'C:\Temp\MyDll.dll'WITH PERMISSION_SET = EXTERNAL_ACCESS剩下的就是使用正确的连接字符串。显然不是enlist=false与结合使用connection=true。这是我使用的连接字符串的例子。
- L- K$ B6 X- L4 g5 I8 gstring connStr = @"data source=serverName\instanceName;initial catalog=DBName;integrated security=SSPI;enlist=false";而且有效! |
|