我正在从数据库表中读取一些数据。数据库中的一个字段" VendorList"返回逗号分隔的供应商列表或只返回一个ID。
Ex:" 1256,553,674"或" 346"
我需要做几件事:
在创建新对象和"供应商"时,会在.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有点新意,你能提供清理这个烂摊子的任何提示吗?
正如您所看到的,我正在使用两个三元运算符。第一个是检测它是否以逗号分隔列表。第二个是检测逗号分隔列表是否有值。
答案 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));
vendorIds
,您可以向未来的程序员指出此变量的含义。在他们理解一般意图之前,他们不必完全理解所有LINQ代码。vendors
中的每个值重新解析整个供应商列表两次。此代码解析一次,并重复使用数据结构进行所有ID检查。 (如果您有大量供应商ID,则可以vendorIds
成为HashSet<>
来进一步提高效果。)如果您的输入是空字符串,RemoveEmptyEntries
部分将确保您最终得到供应商ID的空列表,因此没有匹配的供应商。如果您的输入只有一个没有逗号的值,则最终会在列表中显示一个ID。
请注意,这与原始代码的行为完全不同,因为如果给定null或空null
,则不会将值设置为m.VendorList
。我猜想如果你花时间去思考它,那么实际上有一个空m.VendorList
并不是你期望发生的事情,如果它确实发生了,那么“快速失败”会更好,而不是不知道为什么.Vendors
属性结束了null
。我还猜测,如果你有一个空 .Vendors
属性,那么使用代码来处理正确的代码要比检查null
值更容易。