不,这是不可能的。
扩展方法仅因您尝试调用它们的类型而被发现,而不是基于周围的上下文。
您有问题的最后一行代码会得到一个不同的错误,因为ToSqlParameter无法将结果添加到列表中,但该方法将可用。
“过滤”扩展方法的唯一方法是:
- 它们可以被调用的类型,这里不是一个选项,因为你想要它
object
- 通过命名空间,因此通过显式添加
using X;指令以使其可用的位置。
另一方面,如果所有对象都可以简单地包装在 SqlParameter 中,那么这里有一种不同的方法,使用反射。
这是一个原型(未测试):
public static void AddParameters(this SqlCommand command, object parameters)
{
foreach (var propertyInfo in parameters.GetType().GetProperties())
{
object propertyValue = propertyInfo.GetValue(parameters, null);
command.Parameters.AddWithValue("@" + propertyInfo.Name, propertyValue);
}
}
你会像这样使用它:
public void DeletePersonById(int id)
{
var cmd = new SqlCommand();
cmd.Connection = ...
cmd.CommandText = "delete from persons where person_id = @id");
cmd.AddParameters(new { id });
cmd.ExecuteNonQuery();
...
请注意,此方法仅创建非常基本SqlParameter的对象,您可能希望扩展它以更好地处理特殊类型,例如具有大小的字符串等。
有关我用于简单程序的一些基本代码的更完整示例,请查看此处:Dropbox link to SO16962113.linq。这是一个可以运行的LINQPad程序,它将在本地创建一个 SQL Server 数据库并为查询设置一些虚拟数据。
相关语法(方法在 LINQPad 程序中实现):
using (var conn = new SqlConnection("...").AutoOpen())
{
// prepare a fresh new database
conn.Execute("if exists (select * from sysdatabases where name = 'SO16962113') drop database SO16962113");
conn.Execute("create database SO16962113");
conn.Execute("use SO16962113");
// execute some queries
conn.Execute("create table persons (person_id int primary key not null identity(1,1), person_name varchar(100))");
conn.Execute("insert into persons (person_name) values ('James'), ('Jon'), ('Mary'), ('Jack')");
conn.Query<Person>("select * from persons where person_id in (@id1, @id2)", new { id1 = 2, id2 = 4 }).Dump();
// clean up
conn.Execute("use master");
conn.Execute("drop database SO16962113");
}