我有一个linq查询,通过匹配方法名称将两个表连接在一起。在表中,我需要查找“全局”值,如果找到该值,则将“参数”方法中的子元素相互比较,以确保两个表具有相同的对应物,并且如果一个方法的参数与其他任何一个都不匹配然后返回false。
下面是结果示例。我们可以看到seqEquals找到了一个不等于其他任何方法的“方法”,但是,LINQ查询返回了所有值,我只想提取false的“ seqEquals”,我尝试将字符串进行比较但是,“ where”子句的结果并未按预期进行比较。
{ mOneName = GetItemsJSON, seqEqual = False, mOneParm = [
{
"name": "itemTypes",
"type": "List"
},
{
"name": "textSearch",
"type": "String"
}
], mTwoParm = [
{
"name": "propertyId",
"type": "String"
},
{
"name": "revClassIds",
"type": "List"
},
{
"name": "itemTypes",
"type": "List"
},
{
"name": "textSearch",
"type": "String"
},
{
"name": "eventId",
"type": "String"
}
] }
C#代码
var ST1 = firstOrgST["records"][0]["SymbolTable"]["methods"];
var ST2 = secondOrgST["records"][0]["SymbolTable"]["methods"];
// joins both tables and pulls the methods containing global from the joins
var STDiff =
from one in ST1
join two in ST2
on one.Value<String>("name") equals two.Value<string>("name")
where one["modifiers"].Values().Contains("global")
select new
{
mOneName = one["name"],
seqEqual = one["parameters"].ToString() == two["parameters"].ToString(),
mOneParm = one["parameters"],
mTwoParm = two["parameters"]
};
var errorFound = false;
var errorMethod = "";
foreach (var i in STDiff)
{ Console.WriteLine(i);
if (!i.seqEqual)
{
errorFound = true;
errorMethod = i.mOneName.ToString();
break;
}
}
// if error is found prints to console the class name as well as the method name
if (errorFound)
{
Console.WriteLine(Path.GetFileNameWithoutExtension(symbolTable) + " on method: " + errorMethod + " has different parameters.\n");
isDifferent = true;
}
数据示例:这是表一。表二可能有不同的参数
{
"SymbolTable": {
"methods": [
{
"annotations": [
{
"name": "TestVisible"
}
],
"location": {
"column": 20,
"line": 1056
},
"modifiers": [
"private"
],
"name": "GetItemsJSON",
"parameters": [
{
"name": "propertyId",
"type": "String"
},
{
"name": "revClassIds",
"type": "List"
},
{
"name": "itemTypes",
"type": "List"
},
{
"name": "itemCategories",
"type": "List"
},
{
"name": "textSearch",
"type": "String"
},
{
"name": "eventId",
"type": "String"
}
],
"references": [],
"returnType": "String",
"type": null
},
{
"annotations": [],
"location": {
"column": 26,
"line": 4313
},
"modifiers": [
"static",
"global"
],
"name": "GetItemsJSON",
"parameters": [
{
"name": "itemTypes",
"type": "List"
},
{
"name": "textSearch",
"type": "String"
}
],
"references": [],
"returnType": "String",
"type": null
},
{
"annotations": [],
"location": {
"column": 26,
"line": 4316
},
"modifiers": [
"static",
"global"
],
"name": "GetItemsJSON",
"parameters": [
{
"name": "propertyId",
"type": "String"
},
{
"name": "revClassIds",
"type": "List"
},
{
"name": "itemTypes",
"type": "List"
},
{
"name": "textSearch",
"type": "String"
},
{
"name": "eventId",
"type": "String"
}
]
}
]
}
}
答案 0 :(得分:0)
我建议您将数据表转换为对象列表,然后运行linq查询。
1)使用这种通用方法将DataTable转换为对象列表
private static List<T> ConvertDataTable<T>(DataTable dt)
{
List<T> data = new List<T>();
foreach (DataRow row in dt.Rows)
{
T item = GetItem<T>(row);
data.Add(item);
}
return data;
}
private static T GetItem<T>(DataRow dr)
{
Type temp = typeof(T);
T obj = Activator.CreateInstance<T>();
foreach (DataColumn column in dr.Table.Columns)
{
foreach (PropertyInfo pro in temp.GetProperties())
{
if (pro.Name == column.ColumnName)
pro.SetValue(obj, dr[column.ColumnName], null);
else
continue;
}
}
return obj;
}
2)在对象列表上使用这样的Linq查询
var ST1 = myTableData.ToList();
var ST2 = myTableData.ToList();
var STDiff = from one in ST1
join two in ST2
on one.name equals two.name
where one.modifiers.Contains("global")
select new
{
mOneName = one.name,
seqEqual = CompareParamsAndGetMatchingIndex(one.parameters, two.parameters),
mOneParm = one.parameters,
mTwoParm = two.parameters
};
private int CompareParamsAndGetMatchingIndex(Parameter[] items1, Parameter[] items2)
{
if (items1.Length > items2.Length)
{
return items2.Select((Parameter p, int i) => p.Equals(items1[i]) ? 1 : 0).Sum();
}
else
{
return items1.Select((Parameter p, int i) => p.Equals(items2[i]) ? 1 : 0).Sum();
}
}
public class SymbolTableRoot
{
public Symboltable SymbolTable { get; set; }
}
public class Symboltable
{
public Method[] methods { get; set; }
}
public class Method
{
public Annotation[] annotations { get; set; }
public Location location { get; set; }
public string[] modifiers { get; set; }
public string name { get; set; }
public Parameter[] parameters { get; set; }
public object[] references { get; set; }
public string returnType { get; set; }
public object type { get; set; }
}
public class Location
{
public int column { get; set; }
public int line { get; set; }
}
public class Annotation
{
public string name { get; set; }
}
public class Parameter : IEquatable<Parameter>
{
public string name { get; set; }
public string type { get; set; }
public bool Equals(Parameter other)
{
return other?.name == name && other?.type == type;
}
}