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 块中执行插入操作。

相关推荐
码事漫谈4 小时前
别写Prompt了,现在流行给AI“写循环”
后端
Kyrie_Li5 小时前
Spring Boot Kafka 生产级配置全解析:从入门到精通
spring boot·后端·kafka
Coder_Shenshen6 小时前
西门子S7CommPlus协议鉴权算法原理与流程详解
网络·后端·算法
yuhaiqiang6 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
geovindu8 小时前
python: Functional Options Pattern
开发语言·后端·python·设计模式·惯用法模式·函数式选项模式
卷无止境9 小时前
C++ 存储类说明符(Storage Class Specifier)大横评
c++·后端
用户019027581619 小时前
量化数据的 batch 接口有多好用?从 1 只到 500 只,批量拉数据的正确姿势
后端
rruining10 小时前
Java设计模式——结构型
后端
卷无止境10 小时前
C++ 编程的一大坑:非常量全局变量是"万恶之源"
c++·后端
Sinclair11 小时前
认识安企CMS-系统和模板文件结构
后端