使用C#我试图创建一个列表,其中包含多个元素添加新项目,如果主键不在列表中,否则更新项目if它确实如此。我已经发现了很多关于每个部分的内容,但是我一直在努力将其结合到我迄今为止发现的可行解决方案中。C#更新多元素列表项目,如果项目已经存在,否则将其添加为新项目
下面是编译过的注释代码。
问题: 即使密钥(ReceiptID)已经存在于列表中,因此解决方法是将所有项目添加为新项目,以便我的检查方式出现问题。
也许问题:(编辑:不是问题,因为它按预期工作) 因为我还没有能够测试更新如果存在的部分,我不知道我是否有这种权利。
任何指导表示赞赏。
编辑:(注意:根据WhoIsRich评论,这可能是使用字典而不是列表完成的,这可能会是一个更好,更有效的解决方案,谢谢WhoIsRich)。
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IList<Receipts> receiptList = new List<Receipts>()
// The real app reads through a temporary table in the database
// to pick up the line items of a sale. The objective is to combine those line
// items into a summary list called receipts based on the receipt number. For this
// runnable example, I add some data to the receipt list here.
{
new Receipts() { ReceiptID = 1, TotalPrice = 10, TotalCost = 5, Profit = 5, EmployeeID = 1 },
new Receipts() { ReceiptID = 2, TotalPrice = 15, TotalCost = 6, Profit = 9, EmployeeID = 1 },
new Receipts() { ReceiptID = 3, TotalPrice = 20, TotalCost = 7, Profit = 13, EmployeeID = 1 },
new Receipts() { ReceiptID = 4, TotalPrice = 25, TotalCost = 10.50M, Profit = 14.50M, EmployeeID = 1 },
};
// some dummy data to update list item with. Note: if receiptID is the same as one already in the list, employeeID
// will also be the same. (It's always the same employee that completes a whole transaction).
int[] receiptID = { 3, 4, 5, 5, 6, 7, 7, 8 };
decimal[] totalPrice = { 5, 6, 7, 8, 9, 10, 11, 12 };
decimal[] totolCost = { 2, 2.5M, 3, 3.5M, 4, 4.5M, 5, 5.5M };
decimal[] profit = { 3, 3.5M, 4, 4.5M, 5, 5.5M, 6, 6.5M };
int[] employeeID = { 1, 1, 1, 1, 2, 1, 1, 2 };
// This for loop represents the while loop reading the database table
for (int i = 0; i < 8; i++)
{
// first, check to see if the receiptID is already in the list. This is the
// part I am having trouble with.
Receipts r = new Receipts();
//EDIT:
//if (receiptList.Contains(new Receipts { ReceiptID = receiptID[i] })) <== original in question
//if (receiptList.Any(rc => rc.ReceiptID == receiptID[i])) <== Keyur PATEL's comment to question - Works
//if (receiptList.Any(o => o.ReceiptID == receiptID[i])) <== kurakura88 answer - Works
if (receiptList.Any(receipt => receipt.ReceiptID == receiptID[i])) // <== Eric Wu - Works
// END EDIT
{
// The code never enters here! <<=== This is what I need help with fixing
var tu = receiptList.Single(x => x.ReceiptID == receiptID[i]);
tu.TotalPrice += totalPrice[i];
tu.TotalCost += totolCost[i];
tu.Profit += profit[i];
// receiptID and employeeID are not updated as they don't change in this if loop.
}
else
{
// This should happen if the receiptID is not in the list, but it's happening
// every time.
r.ReceiptID = receiptID[i];
r.EmployeeID = employeeID[i];
r.TotalPrice = totalPrice[i];
r.TotalCost = totolCost[i];
r.Profit = profit[i];
receiptList.Add(r);
}
}
// Below here just displays the results in a sorted maner which is working ok.
var orderByValue = from s in receiptList
orderby s.ReceiptID
ascending
select s;
foreach (var item in orderByValue)
{
Console.WriteLine("Receipt: {0} Employee: {1} TotalPrice: {2} TotalCost: {3} Profit: {4}", item.ReceiptID.ToString(), item.EmployeeID.ToString(), item.TotalPrice.ToString(), item.TotalCost.ToString(), item.Profit.ToString());
}
Console.ReadLine();
}
}
public class Receipts
{
public int ReceiptID { get; set; }
public int EmployeeID { get; set; }
public decimal TotalPrice { get; set; }
public decimal TotalCost { get; set; }
public decimal Profit { get; set; }
}
}
/*
The output I am getting is (note each sale line is added to list):
Receipt: 1 Employee: 1 TotalPrice: 10 TotalCost: 5 Profit: 5
Receipt: 2 Employee: 1 TotalPrice: 15 TotalCost: 6 Profit: 9
Receipt: 3 Employee: 1 TotalPrice: 20 TotalCost: 7 Profit: 13
Receipt: 3 Employee: 1 TotalPrice: 5 TotalCost: 2 Profit: 3
Receipt: 4 Employee: 1 TotalPrice: 25 TotalCost: 10.50 Profit: 14.50
Receipt: 4 Employee: 1 TotalPrice: 6 TotalCost: 2.5 Profit: 3.5
Receipt: 5 Employee: 1 TotalPrice: 7 TotalCost: 3 Profit: 4
Receipt: 5 Employee: 1 TotalPrice: 8 TotalCost: 3.5 Profit: 4.5
Receipt: 6 Employee: 2 TotalPrice: 9 TotalCost: 4 Profit: 5
Receipt: 7 Employee: 1 TotalPrice: 10 TotalCost: 4.5 Profit: 5.5
Receipt: 7 Employee: 1 TotalPrice: 11 TotalCost: 5 Profit: 6
Receipt: 8 Employee: 2 TotalPrice: 12 TotalCost: 5.5 Profit: 6.5
What want to get is (same receiptID's should have values added together to one item in list):
Receipt: 1 Employee: 1 TotalPrice: 10 TotalCost: 5 Profit: 5
Receipt: 2 Employee: 1 TotalPrice: 15 TotalCost: 6 Profit: 9
Receipt: 3 Employee: 1 TotalPrice: 25 TotalCost: 9 Profit: 16
Receipt: 4 Employee: 1 TotalPrice: 31 TotalCost: 13 Profit: 18
Receipt: 5 Employee: 1 TotalPrice: 15 TotalCost: 6.5 Profit: 8.5
Receipt: 6 Employee: 2 TotalPrice: 9 TotalCost: 4 Profit: 5
Receipt: 7 Employee: 1 TotalPrice: 21 TotalCost: 9.5 Profit: 11.5
Receipt: 8 Employee: 2 TotalPrice: 12 TotalCost: 5.5 Profit: 6.5
*/
编辑:纠正if语句之后,现在得到以下结果是正确的:
Receipt: 1 Employee: 1 TotalPrice: 10 TotalCost: 5 Profit: 5
Receipt: 2 Employee: 1 TotalPrice: 15 TotalCost: 6 Profit: 9
Receipt: 3 Employee: 1 TotalPrice: 25 TotalCost: 9 Profit: 16
Receipt: 4 Employee: 1 TotalPrice: 31 TotalCost: 13.00 Profit: 18.00
Receipt: 5 Employee: 1 TotalPrice: 15 TotalCost: 6.5 Profit: 8.5
Receipt: 6 Employee: 2 TotalPrice: 9 TotalCost: 4 Profit: 5
Receipt: 7 Employee: 1 TotalPrice: 21 TotalCost: 9.5 Profit: 11.5
Receipt: 8 Employee: 2 TotalPrice: 12 TotalCost: 5.5 Profit: 6.5
List.Contains是失败的地方,请考虑使用linq:'if(receiptList.Any(rc => rc.ReceiptID = receiptID [i]))' –
它如何包含为测试创建的Receipt对象? – Plutonix
仅供参考:自定义类对象列表上的[.Contains())(http://stackoverflow.com/a/2629158/6741868)。它提到'.Contains()'必须被实现,或'.Equals()'被覆盖,以便使用那些具有自定义类的类。 –