簡體   English   中英

在C#中切換for循環的情況

[英]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循環之后移動將對象添加到列表的行。

此外,你不初始化屬性GroupMembershipUploadInputListListGroupMembershipUploadInput類。 因此它為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM