【问题标题】:Cant access List from another Class无法从另一个班级访问列表
【发布时间】:2014-01-30 15:04:49
【问题描述】:

我正在尝试访问Class 中的List,以便可以在另一个Insert 语句中使用这些值。我的想法是,我使用 excel 电子表格中的值(在 LegalTransactionList Class 中进行)使用 for loop 填充 List。然后,我将把这些值和insert 放入数据库表中(发生在 Helpers Class 中)。我在 lstOfTran.AccountNumber 上收到一条错误消息,指出 LegalTransactionRec 不包含 AccountNumber 的定义。任何帮助将不胜感激。

class LegalTransactionList
{

    public static List<LegalTransactionRec> setTransactions()
    {
        Form1 form = new Form1();
        Workbook workbook = form.excelApp.Workbooks.Open(form.txtbxFilename.Text);

        List<LegalTransactionRec> lstTran = new List<LegalTransactionRec>();

        try
        {

            //workbook = excelApp.Workbooks.Open(txtbxFilename.Text);                      View above comment
            Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item(1);
            Microsoft.Office.Interop.Excel.Range xlRange = worksheet.UsedRange;

            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;

            for (int i = 1; i <= rowCount; i++)
            {
                for (int j = 1; j <= colCount; j++)
                {
                    lstTran.Add(new LegalTransactionRec()
                    {
                        AccountNumber = Form1.CleanString(xlRange.Cells[i, 1].Value2.ToString()),
                        CostAmount = Form1.TryToParse(Form1.CleanAmount(xlRange.Cells[i, 3].Value2.ToString())),
                        SSN = Form1.CleanString(xlRange.Cells[i, 6].Value2.ToString()),
                        TransactionDate = Form1.CheckDate(xlRange.Cells[i, 2].Value2.ToDate()),
                        Description = xlRange.Cells[i, 8].Value2.ToString(),
                        TransactionCode = Form1.CheckNull(xlRange.Cells[i, 4].Value2.ToInt())
                    });
                }
            }

            if (form.validateHeader(worksheet))
            {




            }
        }
        catch (Exception ex)
        {
        }
        return lstTran;

    }
}

class Helpers
{
    public void insertRecords()
    {
        StringBuilder sql = new StringBuilder();
        var lstOfTran = LegalTransactionList.setTransactions();

        using (DataTable dt = DataManager.GetData(sql))
        {
            foreach (DataRow dr in dt.Rows)
            {
                try
                {
                    sql.AppendLine("INSERT INTO LEGAL_TRANSCATIONS (BATCH_ID, ACCOUNT, ATTORNEY_ID, ORG_ID, TRANSACTION_DATE, DATE_INSERTED, TRANSACTION_CODE, AMOUNT, DESCRIPTION, DEBTOR_SSN");
                    sql.AppendLine("VALUES ( (select max(batch_id) from legal_transaction_batch_info)," + lstOfTran.AccountNumber + );
                }
                catch (Exception ex)
                { }
            }
        }
    }
}

public class LegalTransactionRec
{
    public string AccountNumber { get; set; }
    public string CostAmount { get; set; }
    public string SSN { get; set; }
    public int BatchID { get; set; }
    public Attorney Attorney { get; set; }
    public DateTime TransactionDate { get; set; }
    public string Description { get; set; }
    public int TransactionCode { get; set; }
}

public int CheckNull(int intVal)
    {
        int cleanValue;
        if (intVal == null)
        {
            throw new System.ArgumentException("Value cannot be null", "original");
        }
        else
        {
            cleanValue = intVal;
        }

        return cleanValue;
    }

    public string CleanString(String strVal)
    {
        string cleanValue;
        if (strVal == null)
        {
            throw new System.ArgumentException("Value cannot be null", "original");
        }
        else
        {
            cleanValue = Regex.Replace(strVal, " ", "").Replace("$", "").Replace("-", "");
        }

        return cleanValue;
    }

    public string CleanAmount(String amt)
    {
        string cleanAmt;
        if (amt == null)
        {
            throw new System.ArgumentException("Value cannot be null", "original");
        }
        else
        {
            cleanAmt = Regex.Replace(amt, "(", "-").Replace(")", "").Replace("$", "").Replace("[^0-9]+", "").Replace(" ", "");
        }
        return cleanAmt;
    }

    public static void TryToParse(string strAmt)
    {
        decimal decAmt;

        bool result = Decimal.TryParse(strAmt, out decAmt);

    }

    public DateTime CheckDate(DateTime tranDate)
    {
        DateTime date;

        if (tranDate == null)
        {
            throw new System.ArgumentException("Value cannot be null", "original");
        }
        else
        {
            date = tranDate;
        }

        return date;
    }

【问题讨论】:

  • 是否 LegalTransactionRec 包含AccountNumber 属性?
  • 另外,不要吞下异常 - 取出空的 catch{} 块并处理错误或让它冒泡。
  • 在 OP 中添加 LegalTransactionRec 类。
  • @DStanley 这是一个非常粗略的草稿,我希望在添加此类内容之前先让程序的骨架工作。我知道这可能不是做事的最佳方式,但因为我正在学习 C#,所以这就是我喜欢做事的方式。不过谢谢。
  • 那么一开始就不要添加try/catch,让任何错误自然冒出来。您将花费更多时间试图找出发生错误的哪里,因为它们被catch 块抛出。添加 try/catch 当您准备好处理异常时

标签: c# list class


【解决方案1】:

您正在尝试访问lstOfTran 类型的LegalTransactionRec 列表中的属性,该属性不需要AccountNumber 属性。我认为您尝试的是lstOfTran[i].AccountNumber

【讨论】:

    【解决方案2】:

    您正在lstOfTran 上寻找AccountNumber

    var lstOfTran = LegalTransactionList.setTransactions();
    ...
    sql.AppendLine("..." + lstOfTran.AccountNumber);
    

    LegalTransactionList.setTransactions() 返回LegalTransactionRecs 的列表list 没有该属性,但列表中的 items 有。

    如果您打算遍历交易列表,那么它会是这样的:

    StringBuilder sql = new StringBuilder();
    var lstOfTran = LegalTransactionList.setTransactions();
    
    foreach (LegalTransactionRec trans in lstOfTran )
    {
        sql.AppendLine(" INSERT INTO LEGAL_TRANSCATIONS (BATCH_ID, ACCOUNT, ATTORNEY_ID, ORG_ID, TRANSACTION_DATE, DATE_INSERTED, TRANSACTION_CODE, AMOUNT, DESCRIPTION, DEBTOR_SSN" );
        sql.AppendLine(" VALUES ( (select max(batch_id) from legal_transaction_batch_info),"
                      + trans.AccountNumber + );    
                   //   ^-- use loop variable here
    }
    

    其他注意事项:

    • 不要吞下异常 - 要么处理它们,要么让它们冒泡。
    • 如果可以的话,不要附加字符串来生成 SQL - 你会冒 SQL 注入的风险
    • 如果您执行 附加字符串以获取 SQL,请务必在字符串之间添加一个空格。 StringBuilder 将添加一个换行符,可能被 SQL 认可,但比抱歉更安全。
    • 从 excel 读取时,将整个值范围拉入一个数组,然后循环遍历该数组。 xlRange.Cells[i, j] 调用是非常昂贵的 COM 调用。如果您先将所有数据拉入一个数组,您会惊讶于它的运行速度有多快。

    【讨论】:

    • 我是 C# 的新手,所以这种情况超出了我的想象,你说我需要做什么?我需要查看LegalTransactionRec 而不是LegalTransactionList
    • @user2405778 你的代码很混乱——你得到一个事务列表,然后尝试通过传递一个空的 sql 字符串来创建一个DataTable(因为你还没有添加任何东西)并循环超过。您的意思是遍历交易列表吗?
    • 是的,我刚刚注意到,当我添加该行时,我的印象是它会做其他事情。我需要删除它,谢谢指出。
    • @user2405778 我添加了一些提示,如果循环交易是您的意图。
    • 哇,这真的很有道理。感谢您的所有帮助!
    【解决方案3】:

    编辑:

    这一行甚至无法编译:

                    sql.AppendLine("VALUES ( (select max(batch_id) from legal_transaction_batch_info)," + lstOfTran.AccountNumber + );
    

    + 之后发生了什么?


    深入研究:

    AccountNumber = Form1.CleanString(xlRange.Cells[i, 1].Value2.ToString()),
    

    看起来CleanString() 返回了一些意想不到的东西。你能展示一下实现吗?

    【讨论】:

    • 我知道它无法编译,我没有添加任何其他内容,因为 lstOfTran.AccountNumber 给了我一个错误。我将在 OP 中添加干净的字符串
    【解决方案4】:

    setTransactions() 正在返回 List&lt;LegalTransactionRec&gt;

    并且您将 var lstOfTran 设置为从

    返回的列表
    LegalTransactionList.setTransactions();
    

    您需要在列表中指定您尝试访问的项目。

    试试吧:

    lstOfTran[0].AccountNumber
    

    你可能还需要改变

    sql.AppendLine("VALUES ( (select max(batch_id) from legal_transaction_batch_info)," + lstOfTran.AccountNumber + );
    

    sql.AppendLine("VALUES ( (select max(batch_id) from legal_transaction_batch_info)," + lstOfTran.AccountNumber );
    

    注意我删除了lstOfTran.AccountNumber之后的最后一个+

    【讨论】:

    • 那摆脱了错误,谢谢!只是为了确保我得到了一些东西,我需要这样做以指向 AccountNumber 在列表中的位置正确吗?
    • @user2405778 没错。您正在选择第一个。
    • 还有+是因为我将在AccountNumber之后添加来自List的其他项目。我只是在发布代码时忘记删除它。也感谢您清除“为什么”!
    • @user2405778 请注意,lstOfTran[0] 只会提取第一笔交易 - 您对获得的其他交易什么也不做。这可能是正确的,但似乎不太可能。
    猜你喜欢
    • 2017-11-05
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    相关资源
    最近更新 更多