2010-12-17 8 views
4

私はCreateCommand私のDbProviderFactoryがSq​​lClientFactoryと異なる動作をするのはなぜですか?

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); 
} 

に、次のロジックを追加した以外、私はこれをしなかった私はそれがすべてSqlCallsをログに記録する終了時SqlDataSourceは、コマンドを作成し、いつでも私は(追跡可能性SQLXタイプを返されたカスタムDbProviderFactoryを実装SQLプロファイラをアップする必要はありません)。これは私が私が背後にあるコードでは、次の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はこれが標準SqlClientFactoryで働いていても、存在しない「@x_id」ということでした。デバッガを使用すると、MyProviderを使用している場合はx_idのコレクションに1つのパラメータがあり、デフォルトのプロバイダを使用している場合は@x_idであることがわかりました。

これには何らかの理由がありますか、@を自動的に追加する方法がありますか、またはコードビハインドと@があるかどうかについてSqlDataSourceが一致していることを確認してください。
ストアドプロシージャはまだ '@'記号なしで動作します。幸いなことに、このコレクションを直接操作することはありませんが、なぜこれが最初に起こるのか知りたいのですが。

ありがとうございました。

答えて

1

より掘り後、私は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 "@"; 
    } 
} 

ので、それが予想されるプロバイダ名と一致しないので、それだけで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 "@"; 
     } 
    } 

} 
関連する問題