[英]Switch case in for loop in C#
我正在逐行讀取excel。各列標題位於第2行。 但數據從第4行開始。 我想首先檢查列標題,並將第4行的值分別放到關聯的模型屬性中。
所以我想在for循環中使用case語句而不是if else檢查。
但它僅在第一種情況下破裂。 我知道這是有意的,但還有其他更有效的方法嗎?
ListGroupMembershipUploadInput gl = new ListGroupMembershipUploadInput();
for (int rw = 4; rw <= ws.Dimension.End.Row; rw++)
{
//Dictionary<string, string> groupMembershipUploadDict = new Dictionary<string, string>();
int headerCol = 2;
GroupMembershipUploadInput gm = new GroupMembershipUploadInput();
for (int col = ws.Dimension.Start.Column; col <= ws.Dimension.End.Column; col++)
{
string val = ws.Cells[headerCol, col].Value.ToString();
switch (ws.Cells[headerCol, col].Value.ToString())
{
case "Code for the particular Chapter(example,'12345' )" :
gm.chpt_cd = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "Existing Constituent Master Id" :
gm.cnst_mstr_id = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "Prefix of the constituent(Mr, Mrs etc)" :
gm.cnst_prefix_nm = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "First Name of the constituent(Mike)" :
gm.cnst_first_nm = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "Middle Name of the constituent(R.)" :
gm.cnst_middle_nm = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "Last Name of the constituent(Andrien)" :
gm.cnst_last_nm = (ws.Cells[rw, col].Value ?? null).ToString();
break;
case "Address Line 1(Home) - (431 Washington Blvd)" :
gm.cnst_addr1_street1 = (ws.Cells[rw, col].Value ?? null).ToString();
break;
}
gl.GroupMembershipUploadInputList.Add(gm);
}
}
這是我建立的模型類。
public class GroupMembershipUploadInput
{
public string chpt_cd {get;set;}
public string cnst_mstr_id {get;set;}
public string cnst_prefix_nm {get;set;}
public string cnst_first_nm {get;set;}
public string cnst_middle_nm {get;set;}
public string cnst_last_nm {get;set;}
public string cnst_addr1_street1 {get;set;}
}
public class ListGroupMembershipUploadInput
{
public List<GroupMembershipUploadInput> GroupMembershipUploadInputList { get; set; }
}
所以我想將excel數據轉換為具有空值的模型對象列表。
你執行
gl.GroupMembershipUploadInputList.Add(gm);
在內部for循環內部。 這意味着在評估每列后添加對象。 因此,對象可以多次添加到列表中。
在內部for循環之后移動將對象添加到列表的行。
此外,你不初始化屬性GroupMembershipUploadInputList
在ListGroupMembershipUploadInput
類。 因此它為null,並且在嘗試將第一個對象添加到列表時,您將獲得NullReferenceException
。
您需要創建列表:
public class ListGroupMembershipUploadInput
{
public List<GroupMembershipUploadInput> GroupMembershipUploadInputList { get; set; } = new List<GroupMembershipUploadInput>();
}
你需要做這樣的事情來擺脫switch
語句:
ListGroupMembershipUploadInput gl = new ListGroupMembershipUploadInput();
int headerCol = 2;
Dictionary<string, int> map = Enumerable
.Range(ws.Dimension.Start.Column, ws.Dimension.End.Column - ws.Dimension.Start.Column + 1)
.ToDictionary(col => ws.Cells[headerCol, col].Value.ToString(), col => col);
for (int rw = 4; rw <= ws.Dimension.End.Row; rw++)
{
gl.GroupMembershipUploadInputList.Add(new GroupMembershipUploadInput()
{
chpt_cd = ws.Cells[rw, map["Code for the particular Chapter(example,'12345' )"]].Value.ToString(),
cnst_mstr_id = ws.Cells[rw, map["Existing Constituent Master Id"]].Value.ToString(),
cnst_prefix_nm = ws.Cells[rw, map["Prefix of the constituent(Mr, Mrs etc)"]].Value.ToString(),
cnst_first_nm = ws.Cells[rw, map["First Name of the constituent(Mike)"]].Value.ToString(),
cnst_middle_nm = ws.Cells[rw, map["Middle Name of the constituent(R.)"]].Value.ToString(),
cnst_last_nm = ws.Cells[rw, map["Last Name of the constituent(Andrien)"]].Value.ToString(),
cnst_addr1_street1 = ws.Cells[rw, map["Address Line 1(Home) - (431 Washington Blvd)"]].Value.ToString(),
});
}
這有效地移動了gl.GroupMembershipUploadInputList.Add(gm);
在內部for
循環之外。
它還使您的代碼更小,更易於閱讀。
回答你的問題“還有其他更有效的方法嗎?”
1)如果要使用Office Interop,逐個單元格讀取不是最有效的方法。 人們常常不了解一種不那么明顯的方式。
這將一次性返回二維數組,然后循環進行循環。 您仍然需要手動跳過第二行,空值並處理轉換。 但是,這將是更快 ,更清潔:
Worksheets("Sheet1").Range("A1:D10").Value
2)最有效的方法是使用OleDB,然后你不需要安裝Office ,只需免費組件Microsoft Access Database Engine 2010 Redistributable (注意:有x86和x64版本,必須使用你的應用程序)
下面是我編譯的代碼草案/片段,很可能不會起作用,但這些都涉及到緬因州的和平。 這個想法是你使用excel中的數據,比如數據庫和表。 最好的部分是你獲得了IDataReader,因此你逐個讀取行而不將所有內容加載到內存中,所以除了速度之外,這也是RAM-wise。
private IDataReader OpenReader()
{
_strConn = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR={1};IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"",
_fileName, Configuration.HasHeaders ? "Yes" : "No");
conn = new OleDbConnection(_strConn);
conn.Open();
var schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
string sheet = schemaTable.Rows[0]["TABLE_NAME"].ToString();
var schemaTableColumns = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, sheet, null });
// I am taking 1-st sheet here for simplicity
string sheetName = schemaTable
.Rows[0]["TABLE_NAME"].ToString();
var cmd = new OleDbCommand(String.Format("SELECT * FROM [{0}]", sheetName), conn);
cmd.CommandType = CommandType.Text;
return cmd
.ExecuteReader(CommandBehavior.Default);
}
PS。 我決定追求最后一個選項如果需要,我可以在這里給你更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.