2

如何使用 C# 从以下其中 ContractID 为 2 的 xml 文件中选择最后 1 个状态?

<actions>
     <Action>
    <ID>2</ID>
    <ContractID>1</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4002</Status>
</Action>
    <Action>
    <ID>2</ID>
    <ContractID>2</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4005</Status>
</Action>
    <Action>
    <ID>2</ID>
    <ContractID>2</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4008</Status>
</Action>
</actions>

以及如何使用 linq to xml 或任何其他方式选择 top n


什么是相当于以下 sql 查询的 linq to xml 代码:

Select contracts.ID, contracts.ContractNo, 
    (select FieldName from tbl_SysType where ID =
    (select top 1 status from tbl_EmployeesActions where ContractID=contracts.ID and Status is not null order by ID desc ))as ContractStatus
from tbl_Contracts as contracts

如果存在名为 Contracts.xml、SysType.xml 和 EmployeesActions.xml 的 xml 文件,如下 Contracts.xml

<Contracts>
     <Contract>
    <ID>1</ID>
    <ContractNo>Mob124444</ContractNo>      
</Contract>
    <Contract>
    <ID>2</ID>
    <ContractNo>Mob124445</ContractNo>      
</Contract>
</Contracts>

雇员行动.xml

    <actions>
     <Action>
    <ID>2</ID>
    <ContractID>1</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4002</Status>
</Action>
    <Action>
    <ID>2</ID>
    <ContractID>2</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4005</Status>
</Action>
    <Action>
    <ID>2</ID>
    <ContractID>2</ContractID>
    <EmployeeID>1</EmployeeID>
    <Date>2012-09-04 00:00:00.000</Date>
    <Reply/>
    <Status>4008</Status>
</Action>
</actions>

系统类型.xml

<SysTypes>
    <systype>
        <ID>4002</ID>
        <FieldName>New</FieldName>
    </systype>
<systype>
        <ID>4005</ID>
        <FieldName>Opened</FieldName>
    </systype>
<systype>
        <ID>4008</ID>
        <FieldName>Closed</FieldName>
    </systype>
</SysTypes>
4

2 回答 2

5

以下是您的两个要求的代码片段:

XDocument doc = XDocument.Load(@"XMLFile.xml");

var statuses = doc.Descendants("Action")
                  .Where(s => s.Element("ContractID").Value.Equals("2"))
                  .Select(s => s.Element("Status").Value);

选择 ContractID 为 2 的最后状态

var lastStatus = statuses.Last();

选择 ContractID 为 2 的前 N ​​个状态

int N = 2; // assuming TOP 2
var topNStatuses = statuses.Take(N);

对于您的新要求,您可以使用此代码片段来替代您的 SQL 查询:

XDocument employees = XDocument.Load(@"EmployeesActions.xml");
XDocument contracts = XDocument.Load(@"Contracts.xml");
XDocument sysTypes = XDocument.Load(@"Systype.xml");

var result = employees.Descendants("Action")
            .Join(sysTypes.Descendants("systype"),
                e => e.Element("Status") != null ? e.Element("Status").Value : "",
                s => s.Element("ID").Value,
                (e, s) => new
                {
                    ID = e.Element("ID").Value,
                    ContractID = e.Element("ContractID").Value,
                    Status = s.Element("FieldName").Value
                })
            .Where(x => !String.IsNullOrEmpty(x.Status))
            .OrderByDescending(x => x.ID)
            .Take(1)
            .Join(contracts.Descendants("Contract"),
                e => e.ContractID,
                c => c.Element("ID").Value,
                (e, c) => new
                {
                    ContractID = c.Element("ID").Value,
                    ContractNo = c.Element("ContractNo").Value,
                    Status = e.Status
                });
于 2012-11-11T08:55:21.833 回答
4
var result = XElement.Load("data.xml").
                      Descendants("Action").
                      Where(x => x.Element("ContractID").Value == "2")
                      .Select(y => new
                       {
                            id = y.Element("ID").Value,
                            empId = y.Element("EmployeeID").Value,
                            contractId = y.Element("ContractID").Value,
                            date = y.Element("Date").Value
                       });

挑选前 N(1)

var top = result.Take(1);

选择最后的 N(1)

var last = result.Skip(result.Count()-1);
于 2012-11-11T08:58:47.617 回答