LINQ查询将两个表连接在一起以返回错误的值

时间:2019-05-28 15:34:05

标签: c# linq

我有一个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"
          }
        ]
      }
    ]
  }
}

1 个答案:

答案 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;
    }
}