周六加班测试"欢乐"多。。。。。。
平时写代码用习惯了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
中是否存在具有相同键值对的字典。也可以通过以下方式来实现:
- 遍历
RawDataList
并比较每个字典的键值对。 - 使用 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
块中执行插入操作。