我实现了一个自定义的DbProviderFactory,它返回了sqlX类型,除了我向CreateCommand添加了以下逻辑
public override DbCommand CreateCommand() { var cmd = new sqlCommand(); if (CommandCreated != null) CommandCreated(cmd,EventArgs.Empty); cmd.StatementCompleted += cmd_StatementCompleted; return cmd; } void cmd_StatementCompleted(object sender,StatementCompletedEventArgs e) { if (StatementCompleted != null) StatementCompleted(sender,e); }
我这样做,所以我可以跟踪sqlDataSource创建一个命令,然后完成记录所有sqlCalls(不需要sql Profiler).这很有效,但是在我实现之后,我得到了以下sqlDataSource的异常
<asp:sqlDataSource ProviderName="MyProvider" ID="sqlDataSource1" runat="server" ConnectionString="<%$ConnectionStrings:default %>" SelectCommandType="StoredProcedure" SelectCommand="dbo.GetX" OnSelecting="sqlDataSource1_Selecting"> <SelectParameters> <asp:Parameter Name="x_id" Type="Byte"/> </SelectParameters> </asp:sqlDataSource>
而这在后面的代码中.
protected void sqlDataSource1_Selecting(object sender,sqlDataSourceCommandEventArgs e) { e.Command.Parameters["@x_id"].Value = "something else"; }
抛出的错误是sqlParameter“@x_id”不存在,即使这适用于标准的sqlClientFactory.使用调试器时,它表明使用MyProvider时集合x_id中有1个参数,使用默认提供程序时表示@x_id.
有什么理由这样做,并且有一些方法我可以自动添加@或者我应该确保代码隐藏和sqlDataSource同意是否存在@.
存储过程仍然可以在没有’@’符号的情况下工作,幸运的是我不会对参数集合进行直接操作,但我想知道为什么会发生这种情况.
谢谢您的帮助.
解决方法
挖掘更多后,我在sqlDataSourceView的源代码中找到了以下内容
protected virtual string ParameterPrefix { get { if (!string.IsNullOrEmpty(this._owner.ProviderName) && !string.Equals(this._owner.ProviderName,"System.Data.sqlClient",StringComparison.OrdinalIgnoreCase)) { return string.Empty; } return "@"; } }
因此,当使用您自己的Provider时,它与预期的Provider名称不匹配,因此它只返回string.Empty.如果您需要这样做,那么您将必须继承sqlDataSource和sqlDataSourceView
public class MysqLDataSource : sqlDataSource { protected override sqlDataSourceView CreateDataSourceView(string viewName) { return new MysqLDataSourceView(this,viewName,this.Context); } } public class MysqLDataSourceView : sqlDataSourceView { private MysqLDataSource _owner; public MysqLDataSourceView(IPsqlDataSource owner,string name,System.Web.HttpContext context) : base(owner,name,context) { _owner = owner; } protected override string ParameterPrefix { get { if (!string.IsNullOrEmpty(this._owner.ProviderName) && !string.Equals(this._owner.ProviderName,"MyProvider",StringComparison.OrdinalIgnoreCase)) { return base.ParameterPrefix; } return "@"; } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。