从平面列表中提取嵌套对象结构
本文关键字:嵌套 对象 结构 提取 平面 列表 | 更新日期: 2023-09-27 18:33:30
我有一个看起来像这样的对象列表:
public class AllTablesView
{
public string ClientId { get; set; }
public string ClientName { get; set; }
public string ContractNumber { get; set; }
public string ContractDate { get; set; }
public string OrderId { get; set; }
public string CarColor { get; set; }
public string CarPlateNumber { get; set; }
public string InvoiceType { get; set; }
public string InvoiceValue { get; set; }
}
实际类比这大,具有至少 12 个不同实体的属性,转换后它们应如下所示:
public class Client
{
public string ClientId { get; set; }
public string ClientName { get; set; }
public IEnumerable<Contract> Contracts { get; set; }
}
public class Contract
{
public string ContractNumber { get; set; }
public string ContractDate { get; set; }
public IEnumerable<Order> Orders { get; set; }
}
public class Car
{
public string CarColor { get; set; }
public string CarPlateNumber { get; set; }
public IEnumerable<Invoice> Invoices { get; set; }
}
public class Invoice
{
public string InvoiceType { get; set; }
public string InvoiceValue { get; set; }
}
就像我说的,这持续了一点,但结构是一样的。我想知道如何从"AllTablesView"类中提取嵌套对象结构。
我尝试使用 Linq 的 Group By,但后来我不得不按每个实体分组,然后循环访问,考虑到实体的数量,这并不切实际。
需要注意的是,我在创建某些对象时有一些逻辑,例如:发票类型是根据客户端 ID 定义的。
编辑:有一件事我忘记了,可能会影响答案。填充这些属性的数据来自数据库,并且不分组。这意味着客户端 ID 将重复多次,但它本质上是同一个客户端,所以我无法再次创建它。对于我在这里公开的每个实体都是如此,对于发票来说可能并非如此。
目标是创建一个表示此"树"的 json 文件,而不会重复。
表示嵌套对象结构的另一种方法是使用 XML。因此,例如,您可以轻松构建一个表示客户端及其相应协定的 XML 字符串,如下所示:
XElement xeBody =
new XElement("Clients",
// for each client in the list of all tables
from client in lstAllTables
//...group by client id into client group
group client by client.ClientId into clientGroup
//... for each client int the group create a <Client> element
select new XElement("Client",
new XAttribute("ClientId", clientGroup.First().ClientId),
new XAttribute("ClientName", clientGroup.First().ClientName),
// for each contract in the current client group create a <Contract> element
from contract in clientGroup
select new XElement("Contract",
new XAttribute("ContractNumber", contract.ContractNumber),
new XAttribute("ContractDate", contract.ContractDate)
)
)
);
以此作为输入:
List<AllTablesView> lstAllTables = new List<AllTablesView>()
{
new AllTablesView() { ClientId = "1", ClientName = "Bob", ContractNumber = "BC1001", ContractDate = "2014-12-07" },
new AllTablesView() { ClientId = "1", ClientName = "Bob", ContractNumber = "BC1002", ContractDate = "2014-12-08" },
new AllTablesView() { ClientId = "1", ClientName = "Bob", ContractNumber = "BC1003", ContractDate = "2014-12-08" },
new AllTablesView() { ClientId = "2", ClientName = "Jim", ContractNumber = "AD1003", ContractDate = "2014-12-08" },
new AllTablesView() { ClientId = "2", ClientName = "Jim", ContractNumber = "AD1004", ContractDate = "2014-12-08" }
};
您将获得以下 XML:
<Clients>
<Client ClientId="1" ClientName="Bob">
<Contract ContractNumber="BC1001" ContractDate="2014-12-07" />
<Contract ContractNumber="BC1002" ContractDate="2014-12-08" />
<Contract ContractNumber="BC1003" ContractDate="2014-12-08" />
</Client>
<Client ClientId="2" ClientName="Jim">
<Contract ContractNumber="AD1003" ContractDate="2014-12-08" />
<Contract ContractNumber="AD1004" ContractDate="2014-12-08" />
</Client>
</Clients>
您可以摆弄上面的 XML 生成代码以生成所需的 xml 结构,包括 OP 中引用的其余类,并有效地避免任何数据重复。
您终于可以使用Newtonsoft Json将XML序列化为Json。
有什么方法可以从另一个类自动提取一个类。您可以尝试添加提取所需信息的扩展方法,例如:
public static class ExtensionMethods
{
public static Client GetClient(this AllTablesView view)
{
return new Client()
{
ClientID = view.ClientID,
ClientName = view.ClientName,
};
}
}
然后让你的班级看起来更简单一些:
Client client = myAllTableView.GetClient();
可能不是您所希望的答案,但除了一些代码自动生成工具之外,我认为 LINQ 不一定能在这里提供帮助。
编辑:对于手动分组,您可以尝试以下操作来检查它是否已经存在:
Dictionary<int, Client> clients = new Dictionary<int, Client>();
foreach (AllTableView tableView in AllTableViewCollection)
{
if (clients.ContainsKey(tableView.ClientID) == false)
{
clients.Add(tableView.GetClient());
}
}
当然,这是自己做的。其他人可能对通过 LINQ 自动执行此操作的方法有更好的主意。