1

我有这样的想法,使用 SQL VIEWS 来抽象简单的数据库计算(例如对关系的计数)就足够了,并且您不需要过程(== 过程代码)

一个简单的 sql视图+ where子句 >> 有时带有参数的存储过程

在提出这一点时,我设想了一种无需编写 SQL 且无需编写 where 子句即可检索表/视图数据的方法。

但是,令我惊讶的是,在 ADO.NET 2.0 或更高版本中似乎没有办法实现这一点。

让我告诉你我尝试了什么:

  • SqlDataAdapter + SqlCommandBuilder 仍然需要您在字符串中编写“SELECT ... FROM”和WHERE CLAUSE(另外,如果您放置“where”,则不会过多使用 Update/Insert/DeleteCommand)

  • 类型化的 DataSet 只允许您检索_整个 DataTable_s,然后对其应用过滤器。过滤器是字符串,没有转义帮助...(必须双引号!)

  • SQL to Entities 看起来很有希望,但它们似乎:仅限于 MSSQL,生成臃肿的 SQL 查询,生成全新的 DAO 堆栈(除了现有的域模型类),所有这些都需要 .net 3.5+ 等等(也就是说,所有这些对我来说都是缺点)

其他 ORM 也有与 SQL to Entity 类似的问题。

我正在寻找的是一种访问数据库表/视图的强类型方法:

  • 不附带另一套 DAO (KISS)
  • 允许我查询表而不在字符串中写入“SELECTs”(强类型)
  • 允许我过滤(WHERE)具有正确转义参数的表(并且无需事先检索整个数据)
  • 以后可以发布更新/插入/删除

我对.Net 相当陌生,但并不愚蠢:这存在吗?

谢谢。

4

11 回答 11

4

流利的ADO

于 2009-07-15T15:44:05.200 回答
2

我真的不相信如果不使用某种 ORM 或带有编译器的专用 DSL 以某种方式知道您的数据库模式、类型/列信息等,您想要做的事情是可以实现的。

考虑到 C# 是一种通用语言,它的编译器完全不知道你的数据库类型,这就是为什么你不能在不使用一些抽象层的情况下绑定它们,这通常涉及即席 SQL 查询(字符串)、NHibernate 或类似的映射文件(更多字符串)和/或 DAO。

于 2009-07-15T15:26:55.017 回答
2

Subsonic有一个相当轻量级的查询工具,您可以使用它直接使用抽象 SQL 的 Query 对象查询数据库。如果您愿意,您还可以使用它的代码生成工具将您的数据库表映射到 POCO,或者只创建一个强类型模式(用于列/表名等)。

于 2009-07-20T20:23:24.567 回答
1

如果您不想编写 WHERE 子句,一种方法是使用 Filter 对象并添加您想要的条件。例如:

        var sc = new Filter();
        sc.Add("Contacttitle", "Sales Agent");
        sc.Add("city", "london", Logical.Or);
        var customers = D2Bk.Fetch(sc, new Customers());

但是您不想使用 DAO(上面的客户就是这样),因此您必须编写 SQL 语句并指定 where 子句:

        DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE Contacttitle=@PAR1 OR City=@PAR2", "Sales Agent", "london");
于 2009-03-02T23:13:19.470 回答
1

我曾经用存储过程做过类似的事情。基本上,我想在 WHERE 子句中指定要匹配的任何字段排列,但我不想编写 100 个参数列表和 where 子句略有不同的存储过程。

所以,我做了这样的事情:

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)

这将让您在代码中调用 sproc 并只传递您有兴趣过滤的参数,如果您将它们留空,其余的将不会被考虑在内。

所以,你可以做类似的事情

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

编辑:回复评论:您可以通过更改 GetSimpleCustomers 很容易地更改为 DeleteSimpleCustomers

SELECT <columns> FROM SimpleCustomers

DELETE FROM SimpleCustomers 

并保持相同的逻辑。更新也是如此。另外,我将用一个问题来回答一个问题:您有多少表实际上需要这种级别的自定义过滤?语法将非常相似,您可以在一天内完成所有操作(如果您拼凑一个简单的脚本为您编写它,则更少)。

于 2009-07-15T12:38:39.473 回答
1

我假设您已经查看了LINQADO.Net 数据服务,但这些不符合您的某些要求?

本机 ADO.Net 是一个数据库提供程序,因此它提供了一个直接连接到底层数据源的 SQL 接口。有各种基于 CRUB 的解决方案可以在不同程度上模拟您的建议。

我们有一个强烈的内部趋势,将数据库留给数据库团队,并使用 Web 服务作为我们数据库的主要接口,主要是因为仍然需要支持 Delphi 代码库。

实际上不敢相信我忘记添加ADO.Net 实体框架,它被 ADO.Net 数据服务等使用。还有一个 LINQ to Entities 提供程序。

于 2009-07-15T12:44:47.557 回答
1

如果您使用强类型数据集,您可以在 Visual Studio 编辑器中创建参数化查询,方法是在查询中添加前缀为 @ 的标识符。在 Visual Studio 中创建一个 DataSet XSD 文件并创建一个名为 Products 的新表,然后向其中添加一个新查询。

例如:

select * from Products where Category = @category;

这将自动生成填充数据集的方法或获取采用额外参数的数据表。它还将处理转义字符串的属性(使用命令对象上的参数)。我用它相当快地创建了一些超级简单的原型网络应用程序。

于 2009-07-15T20:20:29.540 回答
1

我最近编写了一个用于生成 SQL where 子句的查询“框架”。

主要组件是带有 ToWhereClause() 函数的 BaseQueryArgs 类,该函数使用反射将属性转换为字符串部分。这需要处理转义和正确格式化值的工作。

任何继承 BaseQueryArgs 的类都只需要声明公共属性,最终得到一个强类型查询对象。对于可选属性,您将值设为可为空(引用类型或 Nullable<>),SQL 生成器会过滤掉空值。

您可以使用自定义属性为每个属性定义额外的功能:

  • 与属性名称不同的自定义列名称
  • 自定义值处理(例如用作 BETWEEN 测试表达式的日期值)

这可用于创建具有强类型查询对象的查询,如下所示:

MyCustomQueryArgs args = new MyCustomQueryArgs
{
    ProductFamilyID = 17,
    Region = Regions.Northwest,
    Active = true
};

List<Product> product = QueryProcessor.GetProductsWhere(args);

GetProductsWhere() 显然会调用一些使用生成的 SQL 访问视图的数据方法。

我没有更新/删除的解决方案,但编写一个使用开关或属性来确定表名的方法将对象实例转换为 SQL 语句似乎并不难。

这是非常“自己动手”的,但是这使您可以根据需要自由定制它,并且不包括大量繁重的 ORM/DAO 包装。

于 2009-07-16T01:09:44.333 回答
0

看看Mindscapes Lightspeed产品

它构建了严格类型的 LINQ 可查询模型,从而在各种数据库引擎中生成高效的 SQL 代码,并包括 Memcached 和 Lucene 支持

于 2009-07-16T22:27:17.727 回答
0

我在几个项目中使用过 XPO,他们的新版本对查询有更好的支持。

http://www.devexpress.com/Products/NET/ORM/

然而,与所有这些实施一样,实施并非没有缺点。

于 2009-07-19T03:26:04.497 回答
0

我在我的项目中使用Data Abstract

于 2009-07-20T08:40:28.467 回答