c# 踩坑之List<T>.Contains 方法不适用于比较两个字典对象

周六加班测试"欢乐"多。。。。。。

平时写代码用习惯了list.contains(),好像对它没有太多想法,毕竟也没出过bug。咦,今天怎么突然失效了???

ini 复制代码
                    if (matnrRequest.TableNameList.Contains("T_MAKT"))
                    {
                        DataTable T_MAKT = dsSap.Tables["T_MAKT"];

                        //取出当前存在的物料号&语言代码
                        List<Dictionary<string, string>> RawDataList = new List<Dictionary<string, string>>();
 
                        var query = from p in context.SAP_MAKT
                                     select new
                                     {
                                         p.MATNR,
                                         p.SPRAS
                                     };
                         foreach (var item in query)
                         {
                             Dictionary<string, string> RawData = new Dictionary<string, string>();
                             RawData.Add("MATNR", item.MATNR);
                             RawData.Add("SPRAS", item.SPRAS);
                             RawDataList.Add(RawData);
                         }

 
                         List<SAP_MAKT> sAP_MAKTs = new Tool_Reflection<SAP_MAKT>().ConvertDataTableToList(T_MAKT);
                         if (sAP_MAKTs == null || sAP_MAKTs.Count == 0)
                         {
                             sAP_MAKTs = new List<SAP_MAKT>();
                         }
 
                         sAP_MAKTs.ForEach(t =>
                         {
                             t.CREATETIME = nowDate;
 
                            Dictionary<string, string> data = new Dictionary<string, string>();
                             data.Add("MATNR", t.MATNR);
                             data.Add("SPRAS", t.SPRAS);
 
                             //如果存在,则更新
                             if (RawDataList.Contains(data))
                             {
                                 var q = from p in context.SAP_MAKT
                                         where p.MATNR.Equals(t.MATNR) && p.SPRAS.Equals(t.SPRAS)
                                         select p;
 
                                 foreach (var p in q)
                                 {
                                     p.MAKTX = t.MAKTX;
                                     p.CREATETIME = t.CREATETIME;
                                 }
 
                             }
                             else
                             {
                                 context.SAP_MAKT.Add(t);
                             }
                             
                            
                         });
                        
                         context.SaveChanges();

                     }
                     

上述代码需要实现的功能就是:存在则update,不存在则insert。

测试时发现存在也insert,问题出在哪里?

经过对list.contains()的研究得知:List<T>.Contains 方法默认使用对象的 Equals 方法来比较列表中的每个元素与给定的对象是否相等。对于字典类型,这意味着它会比较两个字典对象的引用,而不是它们的值。

在上述代码中,RawDataList 包含的是字典的列表,而 data 也是一个字典。即使 data 的键值对与 RawDataList 中某个字典的键值对相同,Contains 方法也会返回 false,因为它比较的是两个不同的字典对象的引用。

为了解决这个问题,我们需要自定义比较逻辑来检查 RawDataList 中是否存在具有相同键值对的字典。也可以通过以下方式来实现:

  1. 遍历 RawDataList 并比较每个字典的键值对。
  2. 使用 LINQ 的 Any 方法来简化这个过程。

下面是一个使用 LINQ 的 Any 方法来检查 data 是否存在于 RawDataList 中的示例:

arduino 复制代码
// 检查是否存在具有相同MATNR和SPRAS的字典
bool exists = RawDataList.Any(rd => rd["MATNR"] == data["MATNR"] && rd["SPRAS"] == data["SPRAS"]);
if (exists)
{
   // 如果存在,执行更新操作
}
else
{
   // 如果不存在,执行插入操作
}

这段代码会检查 RawDataList 中是否有任何字典的 MATNR 和 SPRAS 键的值与 data 字典中的相应值相匹配。如果找到匹配的字典,exists 将为 true,然后你可以在 if 块中执行更新操作;如果没有找到匹配的字典,exists 将为 false,你可以在 else 块中执行插入操作。

相关推荐
苏三说技术34 分钟前
继PHP之后,Java也爆出了重大安全漏洞!
后端
程序猿乐锅2 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
code2cat2 小时前
Java高级篇之Hibernate:让对象映射到表,理解持久化与事务
java·后端·hibernate·1024程序员节
Younglina2 小时前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
金銀銅鐵4 小时前
[Java] 用 CLI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
陈随易4 小时前
副业搞钱点子之收入查看器
前端·后端
Profile排查笔记4 小时前
浏览器指纹逆向怎么分析:从网络请求追踪到 JavaScript 采集链
前端·人工智能·后端·自动化
lazy H4 小时前
【计算机网络】第 5 篇:TCP 和 UDP 有什么区别?从 Java 后端场景理解两种传输协议
经验分享·后端·网络协议·tcp/ip·计算机网络·1024程序员节
东宇科技5 小时前
crmeb开源版本安装步骤2026-10-20
后端·php·crmeb
IT_Octopus5 小时前
Apollo 配置中心入门:一所“小学校“读懂 Portal、Meta Server、Config Service
java·后端·spring