C# 确定是从架构生成ExecuteOnQuery还是ExecuteReader
我正在尝试创建一个存储过程/ADO.NET映射机制,其中包含参数的存储过程将成为C# 确定是从架构生成ExecuteOnQuery还是ExecuteReader,c#,sql-server,stored-procedures,ado.net,schema,C#,Sql Server,Stored Procedures,Ado.net,Schema,我正在尝试创建一个存储过程/ADO.NET映射机制,其中包含参数的存储过程将成为 object MyStoredProcedure.Execute(out returnValue, param1, param2, ...) 当试图生成实际的数据检索方法时,问题就出现了。我可以很容易地从信息模式视图中获得所需的大多数模式信息,但我无法可靠地找到过程中应该返回的类型(输出参数vs.SELECT/SqlDataReader vs.两者),以及是调用ExecuteOnQuery还是ExecuteRe
object MyStoredProcedure.Execute(out returnValue, param1, param2, ...)
当试图生成实际的数据检索方法时,问题就出现了。我可以很容易地从信息模式视图中获得所需的大多数模式信息,但我无法可靠地找到过程中应该返回的类型(输出参数vs.SELECT/SqlDataReader vs.两者),以及是调用ExecuteOnQuery还是ExecuteReader
最糟糕的情况是,我可能可以解析过程的文本,但那里有各种各样可能出错的古怪事情
生成代码的原因是应用程序数据库包含数百个存储过程。我们继承了这个项目,所以没有办法对我们没有创建的那么多程序进行思考
实际上,我有两个ADO.NET生成的主要目标:
1) 从应用程序中删除所有字符串文字(SqlCommand创建中存储的过程名称、SqlParameter创建中的参数名称等)。这样,当过程或数据库模式发生更改时,我们可以重新生成ADO.NET包装器,并且由这些更改导致的任何错误都将在编译时捕获
2) 不再需要通过proc来确定参数、返回类型等。因此,基本上,数据库本身成为一个API,所有内部存储过程细节都被抽象掉了。是的;这并不容易。对于简单的情况,您可以尝试运行sp(awooga!),为所有参数传递null,并使用-有点风险(例如,扩展存储过程是stll执行的),而且不健壮,因为TSQL可能会在输入上分支。但这是一种选择
“out”ets应通过元数据提供;“旧”方法是syscolumns
(可能有一种信息模式替代方法可以正确地执行此操作)
作为更新;如果您希望数据库将自身描述为API,则可以考虑UDF用于选择;优点:
- 返回值的元数据是严格的,易于查询
- 它在调用者处是可组合的
syscolumns
(可能有一种信息模式替代方法可以正确地执行此操作)
作为更新;如果您希望数据库将自身描述为API,则可以考虑UDF用于选择;优点:
- 返回值的元数据是严格的,易于查询
- 它在调用者处是可组合的
或;只需使用ORM。LINQtoSQL将很好地使用这种类型的设置(包括可组合性);实体框架肯定会为您完成存储过程的所有艰苦工作。或任何其他人,他们都解决了这个问题。这不是小事;为什么要重新发明它?我认为你不应该担心它。
提供重载不是更好吗&让用户决定调用哪个方法
如果我没有正确理解这个问题,请告诉我。我认为你不应该为此担心。
提供重载不是更好吗&让用户决定调用哪个方法
如果我没有正确理解这个问题,请告诉我。假设您的所有存储过程都是一致的,即每个存储过程最多返回一个结果集,且具有相同的列集,而不管其参数值或数据库的数据状态如何,并且所有输出参数始终写入 并且还假设这是一个开发工具,或者至少是一个构建时工具(而不是运行时工具),并且您可以控制存储过程的内容。。下面是我要尝试的:
假设您的所有存储过程都是一致的,也就是说,每个存储过程最多返回一个结果集,且具有相同的列集,而不管其参数值或数据库的数据状态如何,并且所有输出参数始终写入 并且还假设这是一个开发工具,或者至少是一个构建时工具(而不是运行时工具),并且您可以控制存储过程的内容。。下面是我要尝试的:
select s.id, s.name, t.name as [type], t.length,s.isoutparam
from syscolumns s inner join systypes t
on s.xtype = t.xtype
where id = (select id from sysobjects where name = 'SP NAME')
USE tempdb
GO
IF OBJECT_ID('dbo.TestSP') IS NOT NULL
DROP PROCEDURE dbo.TestSP;
GO
IF NOT EXISTS (SELECT * FROM sys.servers WHERE name = 'Loopback')
BEGIN
EXEC sp_addlinkedserver @server = 'Loopback', @srvproduct = '',
@provider = 'SQLOLEDB', @datasrc = @@servername
END
GO
CREATE PROC dbo.TestSP
AS
SELECT 1 as [ID], 'Name' as [Name], 'Boston' as [City]
GO
DECLARE @MyXML XML
SELECT @MyXML = (SELECT * FROM
(SELECT *
FROM OPENQUERY(Loopback,'SET FMTONLY ON;
EXEC tempdb.dbo.TestSP;
SET FMTONLY OFF')) vw FOR XML AUTO, XMLSCHEMA)
SELECT @MyXML