如何在C#中的datagridview上显示我的查询结果?

时间:2019-02-20 13:42:02

标签: c# xml

我有2个xml文件: 一个是我需要过滤的大日志文件(原始数据), 另一个用作配置文件,用于指定我的查询以从大型日志文件中过滤数据。 这是我的两个xml文件的样子:

需要过滤的大型日志文件(下面仅显示一小部分)

<?xml version="1.0" encoding="UTF-8"?>
<Logging S="T006" version="2" >
<Log Date="2018-11-21" Severity="Info" id="22" ID="Opened" Msg="some text"/>
<Log Date="2018-11-21" Severity="Info" id="76" ID="Auth"/>
<Log Date="2018-11-21" Severity="Info" id="60" ID="Up"/>
<Log Date="2018-11-21" Severity="Info" id="22" ID="Opened" Msg="some text"/>
<Log Date="2018-11-21" Severity="Info" id="96" ID="Locked"/>
<Log Date="2018-11-21" Severity="Info" id="84" ID="Done"/>
<Log Date="2018-11-21" Severity="Info" id="57" ID="Idle"/>
<Log Date="2018-11-21" Severity="Info" id="10" ID="Inspected" Pos="12"/>
<Log Date="2018-11-21" Severity="Info" id="148" ID="Started"/>
<Log Date="2018-11-21" Severity="Error" id="38" ID="TechError" Msg="too low"/>
<Log Date="2018-11-21" Severity="Error" id="38" ID="TechError" Msg="too large"/>
<Log Date="2018-11-21" Severity="Error" id="38" ID="TechError" Msg="disabled"/>
<Log Date="2018-11-21" Severity="Error" id="38" ID="TechError" Msg="disabled"/>
<Log Date="2018-11-21" Severity="Error" id="87" ID="Validation"/>
<Log Date="2018-11-21" Severity="data" id="31" ID="Update" Path="~/Status/" From="T121003" To="T121637"/>
<Log Date="2018-11-21" Severity="data" id="31" ID="Update" Path="~/Status/" From="1" To="0"/>
<Log Date="2018-11-21" Severity="Warning" id="24" ID="Problem" Pos="12"/>
<Log Date="2018-11-21" Severity="Warning" id="26" ID="UI" Msg="popup"/>
<Log Date="2018-11-21" Severity="Warning" id="23" ID="Update" Path="Startup" From="1" To="0"/>
<Log Date="2018-11-21" Severity="Info" id="58" ID="System"/>
<Log Date="2018-11-21" Severity="Error" id="20" ID="Log" Msg="failed"/>
<Log Date="2018-11-21" Severity="System" id="50" ID="System"/>
<Log Date="2018-11-21" Severity="System" id="51" ID="Memory" />
</Logging>

下面是我要用来从中生成查询语句的xml(作为配置文件)

    <?xml version="1.0" encoding="utf-8"?>
<Statuscodes xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Statuscode value="S01" text="Status code S01 ">
    <Triggers id="1">
      <Trigger searchField="Severity" searchText="Error" /> 
      <Trigger searchField="ID" searchText="TechError" /> 
    </Triggers>
    <Causes>
      <Cause shortText="this is the cause" longText="This is a very long description....." />
    </Causes>
    <Solutions>
      <Solution value="SOL01" description="Description of solution" solutionSteps="Follow these steps..." page="2" />
      <Solution value="SOL02" description="Description of solution 2" solutionSteps="or something else" page="3" />
    </Solutions>
  </Statuscode>
  <Statuscode value="S02" text="Status code S02">
    <Triggers id="2">
      <Trigger searchField="Severity" searchText="Error" /> 
      <Trigger searchField="ID" searchText="TechError" /> 
      <Trigger searchField="Msg" searchText="disabled" /> 
    </Triggers>
    <Causes>
      <Cause shortText="2-this is the cause" longText="This is a very long description....." />
    </Causes>
    <Solutions>
      <Solution value="2-SOL01" description="Description of solution" solutionSteps="Follow URL" page="2" />
      <Solution value="2-SOL02" description="Description of solution 2" solutionSteps="Do something else" page="3" />
    </Solutions>
  </Statuscode>
</Statuscodes>

到目前为止我的C#代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private List<StatusCode> statusCodes = new List<StatusCode>();

    private void button1_Click(object sender, EventArgs e)
    {
        var dataSet = new DataSet();
        dataSet.ReadXml(@"C:\Users\LargeLogFile.xml");

        var errorLogDataset = new DataSet();
        errorLogDataset.ReadXml(@"C:\Users\configFile.xml");

        foreach (DataRow result in errorLogDataset.Tables["Statuscode"].Rows)
        {
            var statusCode = new StatusCode
            {
                Code = result["value"].ToString(),
                Text = result["text"].ToString()
            };

            var MyQuery = String.Empty;

            foreach (DataRow resultTrigger in errorLogDataset.Tables["Trigger"].Select("Triggers_Id = " + result[0].ToString()))
            {
                var trigger = new Trigger
                {
                    SearchField = resultTrigger["searchField"].ToString(),
                    SearchText = resultTrigger["searchText"].ToString()
                };

                statusCode.Triggers.Add(trigger);

// Questions: is this the right way/syntax to make MyQuery statement?
                MyQuery += trigger.SearchField + " = '" + trigger.SearchText + "' AND ";

            }

            MyQuery = MyQuery.TrimEnd(" AND ".ToCharArray());

//Question: can I pass MyQuery to Select like this?
            DataRow[] temp = dataSet.Tables["Log"].Select(MyQuery);

            statusCodes.Add(statusCode);
            var bindingSource = new BindingSource
            {
                DataSource = dataSet,
                DataMember = "Log"
            };

            dataGridView1.DataSource = bindingSource;
        }
    }
}

class Trigger
{
    public string SearchField { get; set; }
    public string SearchText { get; set; }
}

class StatusCode
{
    public string Code { get; set; }
    public string Text { get; set; }

    public List<Trigger> Triggers { get; private set; }

    public StatusCode()
    {
        Triggers = new List<Trigger>();
    }
}

我的目的是从数据集中检索MyQuery结果数据,并在gridview中显示行和列。因此,通过这种方式,我可以过滤大型日志文件,并且只能看到我选择的内容。 通过断点,我可以看到:

  • MyQuery =“ Severity ='Error'AND ID ='TechError'”的结果
  • errorLogDataset创建7个表:{状态代码,触发器,触发器,原因,原因,解决方案,解决方案}。尽管我的xml文件中没有属性Triggers_Id,但是运行代码会在Triggers表中创建此列。与Statuscode表的Statuscode_Id相同,Solutions的等等。为什么会这样?
  • 临时我从LogFile中获取所有行,不仅是我在MyQuery中选择的行,我如何从LogFile中获取MyQuery的结果数据并仅在datagridview中显示这些行?

我知道有很多关于datagridview和LINQ以及过滤的资料和实例,但是我找不到一些更具体和与我的情况类似的答案。请告诉我,我在代码中做错了什么? 预先感谢。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Globalization;


namespace StatusTable
{
    public partial class Form1 : Form
    {
        const string LOG_XML = @"C:\Users\LargeLogFile.xml";
        const string STATUS_XML = @"C:\Users\configFile.xml";
        enum Logic
        {
            AND,
            OR
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DataTable logging = new DataTable();
            logging.Columns.Add("Date", typeof(DateTime));
            logging.Columns.Add("Severity", typeof(string));
            logging.Columns.Add("id", typeof(string));
            logging.Columns.Add("ID", typeof(string));
            logging.Columns.Add("Msg", typeof(string));

            XDocument docLog = XDocument.Load(LOG_XML);

            foreach (XElement log in docLog.Descendants("Log"))
            {
                DateTime date = (DateTime)log.Attribute("Date");
                string severity = (string)log.Attribute("Severity");
                string id = (string)log.Attribute("id");
                string ID = (string)log.Attribute("ID");
                string msg = (string)log.Attribute("Msg");

                logging.Rows.Add(new object[] { date, severity, id, ID, msg });
            }


            XDocument docStatus = XDocument.Load(STATUS_XML);
            Logic logic = Logic.AND;
            foreach (XElement Statuscode in docStatus.Descendants("Statuscode"))
            {

                DataTable status = null;
                List<KeyValuePair<string, object>> searchFields = new List<KeyValuePair<string, object>>();
                foreach (XElement trigger in Statuscode.Descendants("Trigger"))
                {
                    string searchField = (string)trigger.Attribute("searchField");
                    string searchText = (string)trigger.Attribute("searchText");

                    switch (searchField)
                    {
                        case "Date":
                            // logging.AsEnumerable().Where(x => x.Field<DateTime>(searchField) == (DateTime)trigger.Attribute(searchText)).CopyToDataTable(status, LoadOption.Upsert);
                            searchFields.Add(new KeyValuePair<string, object>(searchField, (DateTime)trigger.Attribute("searchText")));
                            break;
                        default:
                            //logging.AsEnumerable().Where(x => x.Field<string>(searchField) == searchText).CopyToDataTable(status, LoadOption.Upsert);
                            searchFields.Add(new KeyValuePair<string, object>(searchField, (string)trigger.Attribute("searchText")));
                            break;
                    }

                    dataGridView1.DataSource = status;

                }
                switch (logic)
                {
                    case Logic.AND:
                        status = logging.AsEnumerable()
                            .Where(x => searchFields.All(field => (field.Value.GetType() == typeof(DateTime)) ? x.Field<DateTime>(field.Key) == (DateTime)field.Value : x.Field<string>(field.Key) == (string)field.Value))
                            .CopyToDataTable();
                        break;

                    case Logic.OR:
                        status = logging.AsEnumerable()
                            .Where(x => searchFields.Any(field => (field.Value.GetType() == typeof(DateTime)) ? x.Field<DateTime>(field.Key) == (DateTime)field.Value : x.Field<string>(field.Key) == (string)field.Value))
                            .CopyToDataTable();
                        break;

                }
            }

        }
    }
}

1 个答案:

答案 0 :(得分:0)

我创建了数据表,您可以将其用作搜索结果的数据源。我使用Xml Linq。每次搜索的结果均处于数据表状态。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;

namespace WindowsFormsApplication37
{
    enum Logic
    {
        AND,
        OR
    }

    public partial class Form1 : Form
    {
        const string LOG_XML_FILENAME = @"c:\temp\test1.xml";
        const string STATUS_XML_FILENAME = @"c:\temp\test2.xml";
        public Form1()
        {
            InitializeComponent();
        }
        private List<StatusCode> statusCodes = new List<StatusCode>();

        private void button1_Click(object sender, EventArgs e)
        {

            DataTable errorLogDatatable = new DataTable();
            errorLogDatatable.Columns.Add("Date", typeof(DateTime));
            errorLogDatatable.Columns.Add("Severity", typeof(string));
            errorLogDatatable.Columns.Add("id", typeof(string));
            errorLogDatatable.Columns.Add("ID", typeof(string));
            errorLogDatatable.Columns.Add("Msg", typeof(string));

            XDocument docLog = XDocument.Load(LOG_XML_FILENAME);

            foreach (XElement log in docLog.Descendants("Log"))
            {
                DateTime date = (DateTime)log.Attribute("Date");
                string severity = (string)log.Attribute("Severity");
                string id = (string)log.Attribute("id");
                string ID = (string)log.Attribute("ID");
                string msg = (string)log.Attribute("Msg");

                errorLogDatatable.Rows.Add(new object[] { date, severity, id, ID, msg });
            }

            XDocument docStatus = XDocument.Load(STATUS_XML_FILENAME);
            Logic logic = Logic.AND;
            foreach (XElement Statuscode in docStatus.Descendants("Statuscode"))
            {
                StatusCode statusCode = new StatusCode()
                {
                    Code = (string)Statuscode.Attribute("value"),
                    Text = (string)Statuscode.Attribute("text")
                };
                statusCodes.Add(statusCode);
                DataTable status = null;
                foreach (XElement trigger in Statuscode.Descendants("Trigger"))
                {

                    string searchField = (string)trigger.Attribute("searchField");
                    string searchText = (string)trigger.Attribute("searchText");

                    statusCode.Triggers.Add(new Trigger() { SearchField = searchField, SearchText = (string)trigger.Attribute("searchText") });
                }

                switch (logic)
                {
                    case Logic.AND:
                        status = errorLogDatatable.AsEnumerable()
                            .Where(x => statusCode.Triggers.All(field => x.Field<string>(field.SearchField) == field.SearchText))
                            .CopyToDataTable();
                        break;
                    case Logic.OR:
                        status = errorLogDatatable.AsEnumerable()
                            .Where(x => statusCode.Triggers.Any(field => x.Field<string>(field.SearchField) == field.SearchText))
                            .CopyToDataTable();
                        break;
                }

                var bindingSource = new BindingSource
                {
                    DataSource = status,
                };

                dataGridView1.DataSource = bindingSource;

            }
        }
    }

    class Trigger
    {
        public string SearchField { get; set; }
        public string SearchText { get; set; }
    }

    class StatusCode
    {
        public string Code { get; set; }
        public string Text { get; set; }

        public List<Trigger> Triggers { get; private set; }

        public StatusCode()
        {
            Triggers = new List<Trigger>();
        }
    }
}