转换数组并执行包含

时间:2014-05-20 03:57:03

标签: c# linq

我正在从数据库表中读取一些数据。数据库中的一个字段" VendorList"返回逗号分隔的供应商列表或只返回一个ID。

Ex:" 1256,553,674"或" 346"

我需要做几件事:

  • 将此字符串转换为int []
  • 执行"包含"针对IEnumerable集合。
  • 返回该集合并将其分配给一个属性。

在创建新对象和"供应商"时,会在.Select内部调用此代码。是该新对象的属性。

以下是我目前正在使用的代码:

Vendors = (m.VendorList.Contains(","))
              ? (from v in vendors
                 where m.VendorList.Split(',')
                                   .Select(n => Convert.ToInt32(n))
                                   .ToArray()
                                   .Contains(v.VendorID)
                 select v).ToList()
              : (string.IsNullOrEmpty(m.VendorList))
                    ? null
                    : (from s in vendors
                       where s.VendorID == int.Parse(m.VendorList)
                       select s).ToList()

代码有效,但看起来非常混乱,如果另一个开发人员试图重构它,将很难维护。

我对linq有点新意,你能提供清理这个烂摊子的任何提示吗?

正如您所看到的,我正在使用两个三元运算符。第一个是检测它是否以逗号分隔列表。第二个是检测逗号分隔列表是否有值。

5 个答案:

答案 0 :(得分:2)

试试这个。我相信这相当于你要做的事情。如果我错了,请纠正我。

您可以在一行代码中执行以下操作,但我认为这样更可读(可维护)。

var Vendors = new List<int>();

if (m.VendorList != null)
    Vendors.AddRange(vendors.Where(v => m.VendorList
                                         .Split(',')
                                         .Select(y => Convert.ToInt32(y))
                                         .Contains(v))
                            .Select(v => v));

答案 1 :(得分:1)

Vendors = from v in vendors
          let vendorList = from idString in m.Split(',')
                           select int.Parse(idString)
          where vendorList.Contains(v.VendorID)
          select v;

无需检查是否存在“,”。

答案 2 :(得分:0)

你可以试试这个:

string str = "356"; //"1256,553,674";

string[] arr = str.Split(',');

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

foreach (string s in arr)
{
    lst.Add(Convert.ToInt32(s));
}

列表将包含字符串中的所有数字

答案 3 :(得分:0)

string str = "1256,553,674";

IEnumerable<int> array = str.Split(',').Select(n => Convert.ToInt32(n)).ToArray();

答案 4 :(得分:0)

在这种情况下,我建议从LINQ语句中删除部分内容:

var vendorIds = m.VendorList
    .Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries)
    .Select(n => Convert.ToInt32(n))
    .ToArray();

someObj.Vendors = vendors.Where(v => vendorIds.Contains(v.VendorID));
  1. 这更具可读性。通过将变量赋值给vendorIds,您可以向未来的程序员指出此变量的含义。在他们理解一般意图之前,他们不必完全理解所有LINQ代码。
  2. 这样做会更好。在原始代码中,您将为vendors中的每个值重新解析整个供应商列表两次。此代码解析一次,并重复使用数据结构进行所有ID检查。 (如果您有大量供应商ID,则可以vendorIds成为HashSet<>来进一步提高效果。)
  3. 如果您的输入是空字符串,RemoveEmptyEntries部分将确保您最终得到供应商ID的空列表,因此没有匹配的供应商。如果您的输入只有一个没有逗号的值,则最终会在列表中显示一个ID。

    请注意,这与原始代码的行为完全不同,因为如果给定null或空null,则不会将值设置为m.VendorList。我猜想如果你花时间去思考它,那么实际上有一个空m.VendorList并不是你期望发生的事情,如果它确实发生了,那么“快速失败”会更好,而不是不知道为什么.Vendors属性结束了null。我还猜测,如果你有一个 .Vendors属性,那么使用代码来处理正确的代码要比检查null值更容易。