我偶然遇到过这种情况,我觉得我总是在编写无用的代码。我正在寻找一种最有效的方法来比较列表中字段的值与另一个列表。
例如,假设我有一个视图模型,如下所示:
public class UserContractAddDTO
{
public string ContractId { get; set; }
public bool ContractSelected { get; set; }
public string UserName { get; set; }
}
我将表的值放入此视图模型中,然后将其作为IEnumerable传递回来:
IEnumerable<UserContractAddDTO> jsonArray
现在我有了这个IEnumerable的UserContractAddDTO,我需要遍历它来比较数据库中已存在的值。
我们假设ContractSelected已针对某些行进行了更新,因此将其设置为true。通常我会使用foreach循环,但它需要知道该行是否已存在以避免重复行。
foreach (UserContractAddDTO u in jsonArray)
{
var a = u.ContractId.ToString();
if (u.ContractSelected == true)
{
foreach (UserPlanSponsorContract up in UserContractList)
{
if (up.PlanSponsorContractId.ToString() == a && up.UserId == userId)
{
//update row
var row = _context.UserPlanSponsorContracts.Where(r => r.PlanSponsorContractId.ToString() == u.ContractId && r.UserId == userId).FirstOrDefault();
row.IsVerified = true;
_context.SaveChanges();
}
else
{
//add row
_context.UserPlanSponsorContracts.Add(new UserPlanSponsorContract
{
UserId = userId,
PlanSponsorContractId = Convert.ToInt32(u.ContractId),
IsVerified = true,
ContractAdminEmailSent = false,
AppliedDate = DateTime.Now,
ReverifyReminder = 0
});
_context.SaveChanges();
}
}
}
else
{
foreach (UserPlanSponsorContract up in UserContractList)
{
if (up.PlanSponsorContractId.ToString() == a && up.UserId == userId)
{
//update row
var row = _context.UserPlanSponsorContracts.Where(r => r.PlanSponsorContractId.ToString() == u.ContractId && r.UserId == userId).FirstOrDefault();
row.IsVerified = false;
_context.SaveChanges();
}
}
}
}
这是我尝试过的一种方法,但我正在寻找一种更有效的方法。想法?
答案 0 :(得分:2)
作为一般规则,您需要采取的方法很大程度上取决于程序的结构。它基本上归结为引用类型相等与值相等。
如果两个列表中的对象实际上是同一个对象,则执行以下操作:
var diff = myList.Except(myOtherList).ToList();
如果在你的情况下,你正在处理价值相等(两个不同的对象,但相同的&#34;值&#34;),那么你首先需要告诉C#是什么让你的对象的两个实例相等。你需要定义相等。
为此,有两种思想流派。您可以修改现有的类并使其实现IEquatable
,或者您可以创建一个实现IEqualityComparer
的全新类,它将用于比较您的类的实例。
您可以在this的Prashanth Thurairatnam回答中看到前一种方法的详细示例,this的Jon Skeet回答中的后一种方法之一。
在这两种情况下,您都必须实施两种方法Equals(T, T)
和GetHashCode(T)
。这些方法将用于确定使对象的两个实例相等的原因。一旦你完成了,你需要的唯一代码就是我上面写的那些代码(唯一的区别是,如果你采用IEqualityComparer
方法,你还必须提供你的比较器作为参数。)
答案 1 :(得分:0)
LINQ并非真正用于更新,因此您通常仍需要foreach
循环来处理来自LINQ的结果,但您不需要重复这么多。在不知道UserContractList
来自何处的情况下,我无法说明是否可以进一步简化。
foreach (UserContractAddDTO u in jsonArray) {
var intContractId = Convert.ToInt32(u.ContractId);
foreach (UserPlanSponsorContract up in UserContractList) {
if (up.PlanSponsorContractId == intContractId && up.UserId == userId) {
//update row
var row = _context.UserPlanSponsorContracts.Where(r => r.PlanSponsorContractId == intContractId && r.UserId == userId).FirstOrDefault();
row.IsVerified = u.ContractSelected;
}
else {
//add row
_context.UserPlanSponsorContracts.Add(new UserPlanSponsorContract {
UserId = userId,
PlanSponsorContractId = intContractId,
IsVerified = true,
ContractAdminEmailSent = false,
AppliedDate = DateTime.Now,
ReverifyReminder = 0
});
}
}
_context.SaveChanges();
}
答案 2 :(得分:0)
using System;
using System.Collections.Generic;
namespace SwapArrayVal
{
class A
{
public int ID { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<A> list = new List<A>();
list.Add(new A() { ID = 1, Name = "Pradeep" });
list.Add(new A() { ID = 2, Name = "Binod" });
IEnumerable<A> en1 = list;
List<A> list2 = new List<A>();
list2.Add(new A() { ID = 1, Name = "Pradeep" });
list2.Add(new A() { ID = 2, Name = "Binod" });
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string outputOfInts = serializer.Serialize(list);
string outputOfFoos = serializer.Serialize(list2);
IEnumerable<A> en2 = list2;
if (outputOfInts == outputOfFoos)
{
Console.Write("True");
}
Console.ReadLine();
}
}
}
您可以在此处比较两个IEnumerable列表