【问题标题】:Next Number Generate in LINQ在 LINQ 中生成下一个数字
【发布时间】:2013-04-25 03:19:39
【问题描述】:

我在 sql 表列中有以下类型的列表。

IT-001
IT-002
IT-003
IT-004

我想使用 LINQ 生成下一个代码。目前我正在使用下面的代码。我想知道是否可以使用纯 LINQ 查询而不使用 C# 代码来实现它。如果是怎么办?

 private StockDataClassesDataContext dc;

        public string getNextItemCode()
        {
            dc = new StockDataClassesDataContext();

            List<string> code = (from tbItem in dc.tblItems
                                select tbItem.ItemCode).ToList<string>();


            List<int> Numbers = new List<int>();

            foreach (string item in code)
            {
                string[] arr = item.Split('-');

                Numbers.Add(Convert.ToInt32(arr[1]));

            }

            int maxNumber = 0;

            maxNumber = Numbers.Count > 0 ? Numbers.Max() : 0;

            int nextNumber = maxNumber + 1;

            string itemCode = "IT-"+nextNumber;

            return itemCode;
        }

【问题讨论】:

  • 为什么不要求数据库通过对该字段进行排序并获取 Last() 来查找最后一个?或者,如果您真的确定它们是连续的,为什么不只是 Count() 它们,添加一个并创建新记录?当然,如果你有两个作家,这一切都不会奏效。
  • 为什么要为此使用 LINQ? getNextItemCode() 是无论如何都需要抽象的东西,所以细节在方法中,那么为什么仅仅为了使用 LINQ 就更难添加错误处理/更难调试呢?仅仅因为 LINQ 可以用来解决很多问题并不意味着它应该或者它是最好的解决方案。

标签: c# asp.net linq


【解决方案1】:
string nextCode = dc.tblItems.Count()==0 ? "IT-001" : // if it's empty, start with IT-001
    "IT-" +
    (int.Parse(dc.tblItems.OrderByDescending(i=>i.ItemCode) // order by code descending
                          .First() // get first one (last code)
                          .ItemCode.Split('-')[1]) // get only the number part
     +1).ToString("000") // add 1 and format with 3 digits

【讨论】:

    【解决方案2】:

    最好的做法是在数据库中为数字创建一个单独的字段。像 SeqNo 列。这样就可以轻松生成下一个号码,也很容易存储。

    【讨论】:

      【解决方案3】:

      如果多个阅读器同时连接,这种生成项目代码的方式将失败,并且最终会得到相同的项目代码。

      你为什么不改变逻辑来避免所有这些问题?

      您可以为项目代码文本部分设置自动增量字段和单独的列。如果您有许多这样的子代码并在主表中添加外键,那也可以存储在单独的表中。

      现在您不必担心如何生成下一个代码,因为数据库会自动增加 id 编号。当您想显示商品代码时,您可以加入 text 部分和 id 部分。

      【讨论】:

      • 实际上在保存记录时会生成号码并处理交易,因此不会有多个用户获得相同ID的风险。感谢您的想法,我应该转发尝试
      【解决方案4】:

      看起来你可以在没有所有列表的情况下做同样的事情。试试这个:

      public string getNextItemCode()
      {
          dc = new StockDataClassesDataContext();
      
          var nextNumber = 
              (from tbItem in dc.tblItems
               select tbItem.ItemCode)
              .AsEnumerable()
              .Select(code => Convert.ToInt32(code.Substring(code.IndexOf("-") + 1))
              .DefaultIfEmpty()
              .Max() + 1;
      
          return "IT-" + nextNumber;
      }
      

      根据您的 Linq 提供程序,您可以在查询中进行整数转换,如下所示:

      public string getNextItemCode()
      {
          dc = new StockDataClassesDataContext();
      
          var nextNumber = 
              (from tbItem in dc.tblItems
               let c = tbItem.ItemCode
               select Convert.ToInt32(c.Substring(c.IndexOf("-") + 1))
              .DefaultIfEmpty()
              .Max() + 1;
      
          return "IT-" + nextNumber;
      }
      

      我将最终返回值基于您的代码,但正如其他人指出的那样,这会产生格式不正确的字符串(IT-1 而不是IT-001)。您可能应该使用格式字符串来让您的生活更轻松:

      return "IT-" + nextNumber.ToString("D3");
      // or
      return string.Format("IT-{0:D3}", nextNumber);
      

      【讨论】:

        猜你喜欢
        • 2016-03-17
        • 1970-01-01
        • 2012-06-19
        • 1970-01-01
        • 1970-01-01
        • 2019-08-18
        • 2020-02-23
        • 2022-01-26
        • 2017-02-16
        相关资源
        最近更新 更多