Question

Je mis en place un DbProviderFactory personnalisé qui retourne les types SQLx sauf que j'ajouté la logique suivante pour 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);
}

Je l'ai fait pour que je puisse suivre chaque fois qu'un SqlDataSource créé une commande et puis quand il a fini de se connecter tous SqlCalls (sans avoir besoin Sql Profiler vers le haut). Cela a fonctionné, mais après avoir mis en œuvre ce que je suis une exception à ce qui suit 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>

et cela dans le derrière de code.

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

L'erreur étant jeté était que le SqlParameter « @x_id » n'existe pas, même si cela a fonctionné avec le SqlClientFactory standard. Lorsque vous utilisez le débogueur, il a montré qu'il y avait 1 paramètre dans la collection x_id lors de l'utilisation MyProvider et @x_id lorsque vous utilisez le fournisseur par défaut.

Y at-il une raison pour cela et est-il une manière que je peux obtenir le @ est ajouté automatiquement ou dois-je faire juste que le code-behind et SqlDataSource d'accord s'il y a un @ ou non.
La procédure stockée fonctionne toujours sans le « @ » signe et, heureusement, je ne fais pas cette manipulation directe de la grande collection de paramètres mais je voudrais savoir pourquoi cela se produit en premier lieu.

Merci pour l'aide.

Était-ce utile?

La solution

Après avoir creusé plus je trouve ce qui suit dans la source de 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 "@";
  }
}

et ainsi lorsque vous utilisez votre propre fournisseur, il ne correspond pas au nom du fournisseur prévu et il retourne juste string.Empty. Si vous avez besoin de faire cela, alors vous devrez sous-classe SqlDataSource et 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 "@";
        }
    }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top