Frage

ich implementiert eine benutzerdefinierte DbProviderFactory, die die SQLX Typen zurückgegeben, außer ich die folgende Logik CreateCommand hinzugefügt

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

Ich tat dies, damit ich verfolgen konnte, wenn ein SqlDataSource einen Befehl erstellt und dann, wenn es fertig, alle SqlCalls einzuloggen (ohne SQL Profiler, um nach oben). Das funktionierte, aber nachdem ich das ich durchgeführt habe eine Ausnahme mit dem folgenden 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>

und dies in dem Code-behind.

protected void SqlDataSource1_Selecting(object sender, SqlDataSourceCommandEventArgs e)
{
    e.Command.Parameters["@x_id"].Value = "something else";
}

Der Fehler geworfen war, dass die SqlParameter „@x_id“ existiert nicht, auch wenn dies mit dem Standard SqlClientFactory gearbeitet. Bei der Verwendung des Debugger es zeigte, dass es ein Parameter in der Sammlung x_id war, als MyProvider verwenden und @x_id wenn der Standardanbieter verwendet wird.

Gibt es einen Grund dafür und gibt es irgendeine Weise, die ich das bekommen kann @ s automatisch hinzugefügt oder sollte ich nur den Code-behind stellen Sie sicher, und die SqlDataSource einig, ob ein @ oder nicht.
Die gespeicherte Prozedur funktioniert noch ohne die ‚@‘ Zeichen und zum Glück kann ich tun, nicht diese direkte Manipulation der Parameter Sammlung viel, aber ich würde gerne wissen, warum dies in erster Linie passiert.

Danke für die Hilfe.

War es hilfreich?

Lösung

Nach dem Graben mehr fand ich die folgenden in der Quelle 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 "@";
  }
}

und so, wenn Sie Ihre eigenen Provider verwenden sie den Namen nicht erwartet Provider übereinstimmt und so es gibt nur string.Empty. Wenn Sie dies tun müssen, dann müssen Sie SqlDataSource und SqlDataSourceView

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top