Sau khi kết nối với cơ sở dữ liệu, tôi có thể lấy tên của tất cả các cột được trả về trong mình SqlDataReader
không?
Sau khi kết nối với cơ sở dữ liệu, tôi có thể lấy tên của tất cả các cột được trả về trong mình SqlDataReader
không?
Câu trả lời:
var reader = cmd.ExecuteReader();
var columns = new List<string>();
for(int i=0;i<reader.FieldCount;i++)
{
columns.Add(reader.GetName(i));
}
hoặc là
var columns = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
SELECT id AS "MyId" FROM table;
Có một GetName
hàm trên SqlDataReader
đó chấp nhận chỉ mục cột và trả về tên của cột.
Ngược lại, có một GetOrdinal
cái lấy tên cột và trả về chỉ mục cột.
GetOrdinal
Hoàn hảo. Tôi đã tìm kiếm GetName
, nhưng giải pháp sạch hơn nhiều cho vấn đề của tôi với GetOrdinal
.
Bạn có thể lấy tên cột từ DataReader.
Đây là phần quan trọng:
for (int col = 0; col < SqlReader.FieldCount; col++)
{
Console.Write(SqlReader.GetName(col).ToString()); // Gets the column name
Console.Write(SqlReader.GetFieldType(col).ToString()); // Gets the column type
Console.Write(SqlReader.GetDataTypeName(col).ToString()); // Gets the column database type
}
Đã được đề cập. Chỉ cần một câu trả lời LINQ :
var columns = reader.GetSchemaTable().Rows
.Cast<DataRow>()
.Select(r => (string)r["ColumnName"])
.ToList();
//Or
var columns = Enumerable.Range(0, reader.FieldCount)
.Select(reader.GetName)
.ToList();
Cái thứ hai sạch hơn và nhanh hơn nhiều. Ngay cả khi bạn lưu trữ GetSchemaTable
theo cách tiếp cận đầu tiên, việc truy vấn sẽ rất chậm.
reader.Cast<IDataRecord>().ToList()
. Tôi tin rằng bạn có thể sử dụng dynamic
từ khóa ở đó thay vì IDataRecord
nhưng không có lợi ích. DataTable
được thiết kế để dễ dàng tải một lần, do đó bạn cũng có thể sử dụng nhưng bạn sẽ mất lợi ích của việc tải theo yêu cầu (với trình đọc dữ liệu bạn có thể ngừng tải tại bất kỳ thời điểm nào), như thế var dt = new DataTable(); dt.Load(reader); return dt.AsEnumerable().ToList();
. Có rất nhiều thư viện có thể tự động hóa việc này cho bạn, tìm chúng ở đây stackoverflow.com/questions/11988441 và ở đây stackoverflow.com/questions/1464883
reader.Cast<IEnumerable<dynamic>>
và .Cast<dynamic>
, nhưng nó nói, Cannot convert method group 'Cast' to non-delegate type 'dynamic'. Did you intend to invoke the method?
tôi đã làm gì sai ở đó? (Tôi đã xem các nguồn của bạn, nhưng họ yêu cầu bạn phải biết tên cột mà tôi không biết)
Nếu bạn chỉ muốn tên cột, bạn có thể làm:
List<string> columns = new List<string>();
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
DataTable dt = reader.GetSchemaTable();
foreach (DataRow row in dt.Rows)
{
columns.Add(row.Field<String>("ColumnName"));
}
}
Nhưng nếu bạn chỉ cần một hàng, tôi thích phần bổ sung AdoHelper của tôi. Bổ sung này là tuyệt vời nếu bạn có một truy vấn dòng đơn và bạn không muốn xử lý bảng dữ liệu trong mã của mình. Nó trả về một từ điển không nhạy cảm của các tên và giá trị cột.
public static Dictionary<string, string> ExecuteCaseInsensitiveDictionary(string query, string connectionString, Dictionary<string, string> queryParams = null)
{
Dictionary<string, string> CaseInsensitiveDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
// Add the parameters for the SelectCommand.
if (queryParams != null)
foreach (var param in queryParams)
cmd.Parameters.AddWithValue(param.Key, param.Value);
using (SqlDataReader reader = cmd.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(reader);
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn column in dt.Columns)
{
CaseInsensitiveDictionary.Add(column.ColumnName, row[column].ToString());
}
}
}
}
conn.Close();
}
}
catch (Exception ex)
{
throw ex;
}
return CaseInsensitiveDictionary;
}
throw ex;
là một thực tế tồi tệ nhất.
Tôi sử dụng phương thức GetSchemaTable , được hiển thị thông qua giao diện IDataReader.
Sử dụng phương pháp mở rộng:
public static List<string> ColumnList(this IDataReader dataReader)
{
var columns = new List<string>();
for (int i = 0; i < dataReader.FieldCount; i++)
{
columns.Add(dataReader.GetName(i));
}
return columns;
}
Bạn chắc chắn có thể.
protected void GetColumNames_DataReader()
{
System.Data.SqlClient.SqlConnection SqlCon = new System.Data.SqlClient.SqlConnection("server=localhost;database=northwind;trusted_connection=true");
System.Data.SqlClient.SqlCommand SqlCmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM Products", SqlCon);
SqlCon.Open();
System.Data.SqlClient.SqlDataReader SqlReader = SqlCmd.ExecuteReader();
System.Int32 _columncount = SqlReader.FieldCount;
System.Web.HttpContext.Current.Response.Write("SqlDataReader Columns");
System.Web.HttpContext.Current.Response.Write(" ");
for ( System.Int32 iCol = 0; iCol < _columncount; iCol ++ )
{
System.Web.HttpContext.Current.Response.Write("Column " + iCol.ToString() + ": ");
System.Web.HttpContext.Current.Response.Write(SqlReader.GetName( iCol ).ToString());
System.Web.HttpContext.Current.Response.Write(" ");
}
}
Đây là bản gốc từ: http://www.dotnetjunkies.ddj.com/Article/B82A22D1-8437-4C7A-B6AA-C6C9BE9DB8A6.dcik