需要在.net中使用数据库表模式获取空数据表

使用sql server表的模式创建Empty DataTable对象的最佳方法是什么?

我认为值得一提的一个声明是SET FMTONLY :

SET FMTONLY ON; SELECT * FROM SomeTable SET FMTONLY OFF; 

由于SET FMTONLY打开时的请求,不会处理任何行或将其发送到客户端。

这可能很方便的原因是因为您可以提供任何查询/存储过程并仅返回结果集的元数据。

所有这些解决方案都是正确的,但如果您想要一个为此方案简化的纯代码解决方案。

由于在ExecuteReader函数上指定了CommandBehavior.SchemaOnly,因此在此解决方案中不返回任何数据( 命令行为文档 )

CommandBehavior.SchemaOnly解决方案将添加SET FMTONLY ON; 在为您执行查询之前执行sql,这样可以保持代码清洁。

 public static DataTable GetDataTableSchemaFromTable(string tableName, SqlConnection sqlConn, SqlTransaction transaction) { DataTable dtResult = new DataTable(); using (SqlCommand command = sqlConn.CreateCommand()) { command.CommandText = String.Format("SELECT TOP 1 * FROM {0}", tableName); command.CommandType = CommandType.Text; if (transaction != null) { command.Transaction = transaction; } SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly); dtResult.Load(reader); } return dtResult; } 

尝试: SELECT TOP 0 * FROM [TableName]

并使用SQLDataAdapter填充DataSet,然后从该DataSet中获取Table。

假设您可以连接到包含要在其执行此操作时复制的表的SQL数据库,则可以使用常规结果集进行数据表转换,使用

 select * from  where 1=2 

作为您的源查询。

这将返回带有源表结构的空结果集。

这是我做的:

 var conn = new SqlConnection("someConnString"); var cmd = new SqlCommand("SET FMTONLY ON; SELECT * FROM MyTable; SET FMTONLY OFF;",conn); var dt = new DataTable(); conn.Open(); dt.Load(cmd.ExecuteReader()); conn.Dispose(); 

效果很好。 谢谢AdaTheDev。

 Class BlankTableWithSourceTableSchema Inherits DataTable Public Sub New(ByVal connstr As String, ByVal sourcetable As String) Try Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr) Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection) adapter.TableMappings.Add("Table", "ABlankTable") adapter.FillSchema(Me, SchemaType.Mapped) End Using Catch ex As Exception End Try End Sub End Class 

这工作:

 Class BlankTableWithSourceTableSchema Inherits DataTable Public Sub New(ByVal connstr As String, ByVal sourcetable As String) Try Using connection As SqlServerCe.SqlCeConnection = New SqlServerCe.SqlCeConnection(connstr) Dim adapter As SqlServerCe.SqlCeDataAdapter = New SqlServerCe.SqlCeDataAdapter("SELECT * FROM " & sourcetable, connection) adapter.TableMappings.Add("Table", "ABlankTable") adapter.FillSchema(Me, SchemaType.Mapped) End Using Catch ex As Exception End Try End Sub End Class 

我知道这是一个老问题,特定于SQL Server。 但是,如果您正在寻找可以跨不同数据库工作的通用解决方案,请使用Richard的解决方案,但修改它以使用"SELECT * FROM {0} WHERE 1=0"并更改类型以使用通用ADO.Net类型IDataReader,IDbCommand等等

大多数现代关系数据库都足够智能,可以识别1 = 0条件,并且不会像常规表扫描查询那样运行它。 我在SQL Server,Oracle和DB2上尝试了这个,表中也有几亿条记录。 在几毫秒的时间内都返回空结果。

您可以随时创建自己的:

  DataTable table = new DataTable("TableName"); table.Columns.Add(new DataColumn("Col1", typeof(int))); table.Columns.Add(new DataColumn("Col2", typeof(int))); table.Columns.Add(new DataColumn("Col3", typeof(string))); table.Columns.Add(new DataColumn("Col4", typeof(int))); table.Columns.Add(new DataColumn("Col5", typeof(string))); 

显而易见的缺点是,只要数据库架构发生变化,您就必须更新代码。