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

相关推荐
子兮曰6 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰6 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝6 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码6 天前
别再前后端各写一套表单校验了
java·后端
大勇前进6 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu6 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile6 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白806 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙6 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端
盖伦发发6 天前
软件工程SOLID 五大设计原则
后端·软件工程