ADO.net而不编写SQL(特别是WHERE)
我的想法是,使用SQL视图来抽象简单的数据库计算(例如关系计数)就足够了,并且不需要过程(=过程代码) 一个简单的sql视图+A其中子句>>有时是一个带有参数的存储过程 在谈到这一点时,我设想了一种无需编写SQL和where子句即可检索表/视图数据的方法 但是,令我惊讶的是,在ADO.NET 2.0或更高版本中似乎没有实现这一点的方法 让我告诉你我试过什么:ADO.net而不编写SQL(特别是WHERE),sql,stored-procedures,ado.net,datatable,views,Sql,Stored Procedures,Ado.net,Datatable,Views,我的想法是,使用SQL视图来抽象简单的数据库计算(例如关系计数)就足够了,并且不需要过程(=过程代码) 一个简单的sql视图+A其中子句>>有时是一个带有参数的存储过程 在谈到这一点时,我设想了一种无需编写SQL和where子句即可检索表/视图数据的方法 但是,令我惊讶的是,在ADO.NET 2.0或更高版本中似乎没有实现这一点的方法 让我告诉你我试过什么: SqlDataAdapter+SqlCommandBuilder仍然要求您以字符串形式编写“SELECT…FROM”和WHERE子句(另
- SqlDataAdapter+SqlCommandBuilder仍然要求您以字符串形式编写“SELECT…FROM”和WHERE子句(另外,如果您将“WHERE”放在字符串中,则不需要太多使用Update/Insert/delete命令)
- 类型化数据集只允许检索整个数据表,然后对其应用过滤器。筛选器是字符串,没有转义帮助。。。(单引号必须加倍!)
- SQL到实体看起来很有希望,但它们似乎:仅限于MSSQL,生成臃肿的SQL查询,生成一个全新的DAO堆栈(除了现有的域模型类),Requiire.net 3.5+等等(也就是说,所有这些都是我的缺点)
- 不附带另一套DAO(K.I.S.S)
- 允许我查询表,而无需在字符串中写入“SELECTs”(强类型)
- 允许我使用正确转义的参数筛选(其中)一个表(并且事先不检索整个数据)
- 以后可以发布更新/插入/删除
谢谢。如果不想编写WHERE子句,一种方法是使用筛选对象并添加所需的条件。例如:
var sc = new Filter();
sc.Add("Contacttitle", "Sales Agent");
sc.Add("city", "london", Logical.Or);
var customers = D2Bk.Fetch(sc, new Customers());
select * from Products where Category = @category;
但是您不想使用DAOs(上面的客户就是这样),因此必须编写SQL语句并指定where子句:
DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE Contacttitle=@PAR1 OR City=@PAR2", "Sales Agent", "london");
如果不想编写WHERE子句,一种方法是使用筛选器对象并添加所需的条件。例如:
var sc = new Filter();
sc.Add("Contacttitle", "Sales Agent");
sc.Add("city", "london", Logical.Or);
var customers = D2Bk.Fetch(sc, new Customers());
select * from Products where Category = @category;
但是您不想使用DAOs(上面的客户就是这样),因此必须编写SQL语句并指定where子句:
DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE Contacttitle=@PAR1 OR City=@PAR2", "Sales Agent", "london");
我曾经用存储过程做过类似的事情。基本上,我想在WHERE子句中指定要匹配的字段的任何排列,但我不想用稍微不同的参数列表和WHERE子句编写100个存储过程 所以,我做了这样的事情:
CREATE PROCEDURE [GetSimpleCustomers]
(
@ID varchar(50) = null,
@Name varchar(50) = null,
@IsActive bit = null,
@Address1 varchar(50) = null,
@Address2 varchar(50) = null,
@City varchar(50) = null,
@State varchar(50) = null,
@Zip varchar(50) = null
)
AS
SELECT ID, Name, IsActive, Address1, Address2, City, State, Zip
FROM SimpleCustomerExample
WHERE (ID = @ID OR @ID is NULL)
AND (Name = @Name OR @Name is NULL)
AND (IsActive = @IsActive or @IsActive is NULL)
AND (Address1= @Address1 or @Address1 is NULL)
AND (Address2= @Address2 or @Address2 is NULL)
AND (City= @City or @City is NULL)
AND (State= @State or @State is NULL)
AND (Zip= @Zip or @Zip is NULL)
这将允许您在代码中调用存储过程,并且只传递您感兴趣的过滤参数,如果将其余参数保留为null,则不会考虑它们
所以,你可以这样做
public List<SimpleCustomer> GetAllCustomersFromOhio()
{
List<SimpleCustomer> list = new List<SimpleCustomer>();
using (SqlCommand cmd = new SqlCommand(blah blah))
{
cmd.Parameters.AddWithValue("State", "Ohio");//or "OH" depending on your convention
using(IDataReader oDR = cmd.ExecuteReader())
{
//hydrate your list of SimpleCustomers from the record set.
}
}
return list;
}
保持同样的逻辑。更新也是如此。
另外,我将用一个问题来回答一个问题:您有多少表实际上需要这种级别的自定义筛选?语法非常相似,您可以在一天内将其全部敲碎(如果您拼凑一个简单的脚本来为您编写它,则所需时间更少)。我曾经用一个存储过程做过类似的事情。基本上,我想在WHERE子句中指定要匹配的字段的任何排列,但我不想用稍微不同的参数列表和WHERE子句编写100个存储过程 所以,我做了这样的事情:
CREATE PROCEDURE [GetSimpleCustomers]
(
@ID varchar(50) = null,
@Name varchar(50) = null,
@IsActive bit = null,
@Address1 varchar(50) = null,
@Address2 varchar(50) = null,
@City varchar(50) = null,
@State varchar(50) = null,
@Zip varchar(50) = null
)
AS
SELECT ID, Name, IsActive, Address1, Address2, City, State, Zip
FROM SimpleCustomerExample
WHERE (ID = @ID OR @ID is NULL)
AND (Name = @Name OR @Name is NULL)
AND (IsActive = @IsActive or @IsActive is NULL)
AND (Address1= @Address1 or @Address1 is NULL)
AND (Address2= @Address2 or @Address2 is NULL)
AND (City= @City or @City is NULL)
AND (State= @State or @State is NULL)
AND (Zip= @Zip or @Zip is NULL)
这将允许您在代码中调用存储过程,并且只传递您感兴趣的过滤参数,如果将其余参数保留为null,则不会考虑它们
所以,你可以这样做
public List<SimpleCustomer> GetAllCustomersFromOhio()
{
List<SimpleCustomer> list = new List<SimpleCustomer>();
using (SqlCommand cmd = new SqlCommand(blah blah))
{
cmd.Parameters.AddWithValue("State", "Ohio");//or "OH" depending on your convention
using(IDataReader oDR = cmd.ExecuteReader())
{
//hydrate your list of SimpleCustomers from the record set.
}
}
return list;
}
保持同样的逻辑。更新也是如此。
另外,我将用一个问题来回答一个问题:您有多少表实际上需要这种级别的自定义筛选?语法非常相似,你可以在一天内把它全部敲碎(如果你拼凑了一个简单的脚本来为你编写它的话,可能会更少)。我想你已经看过了,但是这些不符合你的一些要求 本机ADO.Net是一个数据库提供程序,因此它提供了到底层数据源的直接SQL接口。有各种基于CRUB的解决方案在不同程度上模拟了您的建议 我们有一种强烈的内部趋势,即将数据库留给数据库团队,并使用Webservices作为数据库的主界面,这主要是因为仍然需要支持Delphi代码库
真不敢相信我忘了添加ADO.Net数据服务和其他服务使用的。还有一个LINQ to Entities提供程序。我想您已经看过了,但这些不符合您的一些要求 本机ADO.Net是一个数据库提供程序,因此它提供了到底层数据源的直接SQL接口。有各种基于CRUB的解决方案在不同程度上模拟了您的建议 我们有一种强烈的内部趋势,即将数据库留给数据库团队,并使用Webservices作为数据库的主界面,这主要是因为仍然需要支持Delphi代码库
真不敢相信我忘了添加ADO.Net数据服务和其他服务使用的。还有一个LINQ to Entities提供程序。我真的不相信,如果不使用某种形式的ORM,或者不使用专门的DSL以及某种程度上了解您的数据库模式、类型/列信息等的编译器,您想要做的事情是可以实现的 考虑到C#是一种通用语言,它的编译器完全不知道您的数据库类型,这就是为什么您不能在不使用抽象层的情况下绑定它们,而抽象层通常涉及特殊的SQL查询(字符串)、NHibernate或类似的映射文件(更多字符串)和/或