Почему мой dbProviderFactory работает иначе, чем SQLClientFactory?
-
11-10-2019 - |
Вопрос
Я внедрил пользовательский 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 Up). Это сработало, однако после того, как я реализовал это, я получил исключение со следующим 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. При использовании отладчика он показал, что в коллекции был 1 параметр x_id
когда используешь MyProvider
, а также @x_id
При использовании поставщика по умолчанию.
Есть ли какая-то причина для этого, и есть ли какой-нибудь способ добавить @ @'Add Apocation или я должен просто убедиться, что код и устроение и 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 "@";
}
}
И поэтому при использовании вашего собственного поставщика он не соответствует ожидаемому имени провайдера, и поэтому он просто возвращает 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 "@";
}
}
}