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 中是否有任何字典的 MATNRSPRAS 键的值与 data 字典中的相应值相匹配。如果找到匹配的字典,exists 将为 true,然后你可以在 if 块中执行更新操作;如果没有找到匹配的字典,exists 将为 false,你可以在 else 块中执行插入操作。

相关推荐
摇滚侠33 分钟前
面试实战 问题二十四 Spring 框架中循环依赖问题的解决方法
java·后端·spring
GetcharZp2 小时前
C++日志库新纪元:为什么说spdlog是现代C++开发者必备神器?
c++·后端
三木水2 小时前
Spring-rabbit使用实战七
java·分布式·后端·spring·消息队列·java-rabbitmq·java-activemq
快乐就是哈哈哈2 小时前
一篇文章带你玩转 EasyExcel(Java Excel 报表必学)
后端
快乐就是哈哈哈2 小时前
手把手教你用 Java 写出贪吃蛇小游戏(附源码)
后端
别来无恙1493 小时前
Spring Boot文件下载功能实现详解
java·spring boot·后端·数据导出
公众号_醉鱼Java4 小时前
Elasticsearch文档数迷思:为何count和stats结果打架?深度解析背后机制
后端·掘金·金石计划
程序员爱钓鱼4 小时前
Go语言实战案例:使用Gin处理路由参数和查询参数
后端
bobz9654 小时前
5070TI 本地推理
后端
bobz9655 小时前
gpt-oss-20b-base 是基础模型
后端