2010-12-17 3 views
4

은 내가 CreateCommand내 DbProviderFactory가 SqlClientFactory와 다르게 작동하는 이유는 무엇입니까?

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를 기록 완료되면 내가 추적 할 수있는 이런 짓을

에 다음과 같은 논리를 추가 제외 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

더 나는

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 "@"; 
    } 
} 

SqlDataSourceView

의 소스에 다음과 자신의 공급자를 사용할 때 그래서이 예상 제공자 이름과 일치하지 않습니다 그래서 그냥 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 "@"; 
     } 
    } 

} 
관련 문제