2011-09-17 58 views
1

我想创建一个数据访问层,我可以与任何类型的SQL提供程序重用。我不想要的是有一个switch语句,它指定了获取每个已知提供者的最后创建记录的id的不同方式。 DbConnection是否提供了以通用方式访问最后创建的记录的ID的方法?检索使用DbConnection插入的最后一条记录 - C#

回答

2

我对此不会持乐观态度。一些数据库提供了创建ID值的自动化(例如SQL Server,MySQL)。尽管如此,连接并不会自动为您提供价值;你必须要求它。在SQL Server中,

INSERT INTO FOO (...) VALUES(...); SELECT SCOPE_IDENTITY; 

Oracle甚至没有标识列的概念。生成一个身份值意味着要么取现有身份值的MAX + 1,要么使用SEQUENCE和TRIGGER来添加身份值。无论哪种方式,您都必须将其全部包装在一个事务中以保证正确性;对于SEQUENCE解决方案,您必须运行单独的SELECT来获取序列值(作为事务的一部分)。您可能必须使用MAX + 1方法来做到这一点,但我没有在任何应用程序中走这个方向,所以我不能说明确。具有自动化身份解决方案的数据库不需要事务来包装每个插入身份请求。

一般来说,数据库倾向于支持SQL的方言,而不是一个单一的“标准”,并且它们在访问方法上有所不同。试图支持“共同子集”可能意味着你缩小了可能性太远而无用。采用DbConnection,DbCommand等方法,您将仅限于在应用程序代码中生成GUID,作为摆脱身份列混乱的唯一选择。

另一种解决方案是一个ORM,它将一个模型映射到一个底层(以及隐藏的)访问层。实体框架试图到达那里,但由于EF与模型和连接字符串之间的相互依赖性,生成连接字符串是有问题的。 Codeplex上的IQToolkit项目采用了将LINQ映射到数据库的另一种方法,但它仍然需要插件提供程序,它不仅提供独特的连接实现,还提供SQL格式化程序和语言策略模块,可将生成的SQL形成特定约束数据库实现。

我对此的看法是,DbConnection是错误的地方去寻找一个地方开始你的共同点。确保你理解你需要支持的每个数据库的怪癖 - 这意味着在开始将它们包装在公共访问层之前,你必须对它们进行编程。看看ORM足够了解他们是如何工作的;他们所能提供的真正的共同点始于“给我一个带有这个身份的推荐人记录”,而不是“给我一个连接”。它们不仅隐藏连接和命令,还提供命令生成器,有时与数据库提供者紧密合作。大多数结果都是作为映射到表,模型或特定查询的类(例如,基于LINQ)提供的。

如果您真的想隐藏应用程序其余部分的数据库细节,则必须隐藏所有内容。 ADO.NET中的抽象数据访问类是不够的。

或者你可以回到ODBC上,但除了几乎已经过时,它本身就是一组不同的问题。

+0

我同意@Cylon,我将在您的未来看到switch语句。 –

+0

或代表。代表们提出更简洁的代码。 –

+0

谢谢Cyclon让我的选择真的很清楚。每次我想要支持一个新的数据库时,我都必须添加特殊代码。我也会花一些时间尝试ORM – enamrik