lmo*_*ino 1 c# list nested-lists c#-4.0
我正在尝试编写一个程序,打印出(在字符串变量中)有关mdb数据库的以下信息:
表名称表的总列数
列列表如下:
列名:列数据类型:
为了实现这一点,我使用了两种自定义类型(公共类),当然还有列表.这是我到目前为止的代码(由于这里收集的问题和答案,顺便调整了一小部分):
以下是我创建的用于定义我正在使用的两种新类型的类:
public class ClmnInfo
{
public string strColumnName { get; set; }
public string strColumnType { get; set; }
}
public class TblInfo
{
public string strTableName { get; set; }
public int intColumnsQty { get; set; }
public List<ClmnInfo> ColumnList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是实际获取数据的代码.请记住,我使用OleDB连接到实际数据,一切正常,除了我将在下面描述的问题.作为样品,我目前测试此代码用一个简单的1个表分贝,包含字符串类型的12列1 INT32保存(长整型在Access).
//Here I declare and Initialize all relevant variables and Lists
TblInfo CurrentTableInfo = new TblInfo();
ClmnInfo CurrentColumnInfo = new ClmnInfo();
List<TblInfo> AllTablesInfo = new List<TblInfo>();
//This loop iterates through each table obtained and imported previously in the program
int i = 0;
foreach (DataTable dt in dtImportedTables.Tables)
{
CurrentTableInfo.strTableName = Globals.tblSchemaTable.Rows[i][2].ToString(); //Gets the name of the current table
CurrentTableInfo.intColumnsQty = dt.Columns.Count; //Gets the total number of columns in the current table
CurrentTableInfo.ColumnList = new List<ClmnInfo>(); //Initializes the list which will house all of the columns
//This loop iterates through each column in the current table
foreach (DataColumn dc in dt.Columns)
{
CurrentColumnInfo.ColumnName = dc.ColumnName; // Gets the current column name
CurrentColumnInfo.ColumnType = dc.DataType.Name; // Gets the current column data type
CurrentTableInfo.ColumnList.Add(CurrentColumnInfo); // adds the information just obtained as a member of the columns list contained in CurrentColumnInfo
}
//BAD INSTRUCTION FOLLOWS:
AllTablesInfo.Add(CurrentTableInfo); //This SHOULD add The collection of column_names and column_types in a "master" list containing the table name, the number of columns, and the list of columns
}
Run Code Online (Sandbox Code Playgroud)
我调试了代码并观察了所有变量.它工作得很好(表名和列数正确注册,以及该列的column_names,column_types列表),但是当执行"bad"指令时,AllTablesInfo的内容根本不是它们应该是什么.表名是正确的,以及列数,列列表甚至有12个成员,但列表中的每个成员都是相同的,即我正在检查的数据库的LAST列.任何人都可以向我解释为什么当将CurrentTableInfo添加到AllTablesInfo列表时会以这种方式被覆盖?
您正在创建单个 TblInfo
对象,然后在每次迭代时更改属性.您的列表包含许多对同一对象的引用.只需移动此行:
TblInfo CurrentTableInfo = new TblInfo();
Run Code Online (Sandbox Code Playgroud)
到第一个循环的内部,这一行:
ClmnInfo CurrentColumnInfo = new ClmnInfo();
Run Code Online (Sandbox Code Playgroud)
在嵌套foreach
循环内部,以便您在每次迭代时创建新实例.
下一个:
camelCased
名称而不是名称CamelCased
ClmnInfo
TableInfo
,ColumnInfo
)PascalCased
LINQ之前的更改会使代码看起来像这样:
List<TableInfo> tables = new List<TableInfo>();
int i = 0;
foreach (DataTable dt in dtImportedTables.Tables)
{
TableInfo table = new TableInfo
{
Name = Globals.tblSchemaTable.Rows[i][2].ToString(),
// Do you really need this? Won't it be the same as Columns.Count?
ColumnCount = dt.Columns.Count,
Columns = new List<ColumnInfo>()
};
foreach (DataColumn dc in dt.Columns)
{
table.Columns.Add(new ColumnInfo {
Name = dc.ColumnName,
Type = dc.DataType.Name
});
}
tables.Add(table);
// I assume you meant to include this?
i++;
}
Run Code Online (Sandbox Code Playgroud)
使用LINQ:
List<TableInfo> tables =
dtImportedTables.Tables.Zip(Globals.tblSchemaTable.Rows.AsEnumerable(),
(table, schemaRow) => new TableInfo {
Name = schemaRow[2].ToString(),
// Again, only if you really need it
ColumnCount = table.Columns.Count,
Columns = table.Columns.Select(column => new ColumnInfo {
Name = column.ColumnName,
Type = column.DataType.Name
}).ToList()
}
}).ToList();
Run Code Online (Sandbox Code Playgroud)