C# 需要使用数据库表架构获取.net中的空datatable
使用sql server表的架构创建空DataTable对象的最佳方法是什么?假设您可以在执行此操作时连接到包含要复制的表的sql数据库,您可以使用常规的resultset到DataTable转换,使用C# 需要使用数据库表架构获取.net中的空datatable,c#,.net,sql-server,ado.net,datatable,C#,.net,Sql Server,Ado.net,Datatable,使用sql server表的架构创建空DataTable对象的最佳方法是什么?假设您可以在执行此操作时连接到包含要复制的表的sql数据库,您可以使用常规的resultset到DataTable转换,使用 select * from <tablename> where 1=2 选择*其中1=2 作为源查询 这将返回一个带有源表结构的空结果集。请尝试: 从[TableName]中选择顶部0* 然后使用SQLDataAdapter填充数据集,然后从该数据集获取表。我认为值得一提的一句话
select * from <tablename> where 1=2
选择*其中1=2
作为源查询
这将返回一个带有源表结构的空结果集。请尝试:
从[TableName]中选择顶部0*
然后使用SQLDataAdapter填充数据集,然后从该数据集获取表。我认为值得一提的一句话是: 当SET FMTONLY处于启用状态时,由于请求的原因,不会处理行或将行发送到客户端
这之所以方便,是因为您可以提供任何查询/存储过程,并仅返回结果集的元数据。您始终可以创建自己的:
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)));
一个明显的缺点是,每当数据库架构发生更改时,您都必须更新代码。以下是我所做的:
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
所有这些解决方案都是正确的,但是如果您想要一个针对这个场景进行优化的纯代码解决方案 由于在ExecuteReader函数()上指定了CommandBehavior.SchemaOnly,因此此解决方案中未返回任何数据 CommandBehavior.SchemaOnly解决方案将快速添加集合;在为您执行查询之前使用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;
}
我知道这是一个老问题,专门针对SQL Server。但是,如果您正在寻找能够跨不同数据库工作的通用解决方案,请使用Richard的解决方案,但将其修改为使用
“从{0}中选择*其中1=0”
,并将类型更改为使用通用ADO.Net类型IDataReader、IDbCommand等
大多数现代关系数据库都足够智能,能够识别1=0条件,并且不会像常规的tablescan查询那样运行它。我在SQL Server、Oracle和DB2上尝试过这一点,其中表也只有1亿条记录。All确实会在几毫秒内返回空结果。以下是我所做的,它提供了一个空白数据表,可以随时使用:
SqlConnection _sqlConnection = new SqlConnection ();
_sqlConnection.ConnectionString = @"Data Source=<SQL_Server/Instance>; Initial Catalog=<database_name>; Integrated Security=False; User ID=<user_id>;Password=<passowrd>";
_sqlConnection.Open ();
SqlCommand _sqlCommand = new SqlCommand ( "select * from DatabaseName.dbo.viewName", _sqlConnection );
_dataSet = new DataSet ();
_sqlDataAdapter = new SqlDataAdapter ( _sqlCommand );
_sqlDataAdapter.Fill ( _dataSet );
_schemaTable = new DataTable ();
_sqlDataAdapter.FillSchema ( _schemaTable, SchemaType.Source );
dataGridView.DataSource = _schemaTable;
_sqlConnection.Close ();
SqlConnection\u SqlConnection=newsqlconnection();
_sqlConnection.ConnectionString=@“数据源=;初始目录=;集成安全性=False;用户ID=;密码=”;
_Open();
SqlCommand _SqlCommand=newsqlcommand(“从DatabaseName.dbo.viewName中选择*,_sqlConnection”);
_数据集=新数据集();
_sqlDataAdapter=新的sqlDataAdapter(_sqlCommand);
_sqlDataAdapter.Fill(_数据集);
_schemaTable=newdatatable();
_sqlDataAdapter.FillSchema(_schemaTable,SchemaType.Source);
dataGridView.DataSource=\u schemaTable;
_sqlConnection.Close();
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;
}
SqlConnection _sqlConnection = new SqlConnection ();
_sqlConnection.ConnectionString = @"Data Source=<SQL_Server/Instance>; Initial Catalog=<database_name>; Integrated Security=False; User ID=<user_id>;Password=<passowrd>";
_sqlConnection.Open ();
SqlCommand _sqlCommand = new SqlCommand ( "select * from DatabaseName.dbo.viewName", _sqlConnection );
_dataSet = new DataSet ();
_sqlDataAdapter = new SqlDataAdapter ( _sqlCommand );
_sqlDataAdapter.Fill ( _dataSet );
_schemaTable = new DataTable ();
_sqlDataAdapter.FillSchema ( _schemaTable, SchemaType.Source );
dataGridView.DataSource = _schemaTable;
_sqlConnection.Close ();