c# - 从 POCO C# 中检索部分结构化数据
问题描述
我有一个List<TerminalLink>
我想从中检索一个子集的。请参阅下面的类结构。
该子集由一个“地图”定义,该地图标识ChannelLink
在任何给定场景中选择哪个。ChannelLink
每个场景可能需要多个s,可能来自相同的 s ChannelGroup
,可能来自相同的不同ChannelGroup
s TerminalLink
,也可能来自我原始内存列表中的多个TerminalLink
s。
只有在 ChannelGroupLink 和 TerminalLink 也匹配时才能选择 ChannelLink(我猜它们是索引的一部分)。
我尝试了各种 Linq 和 foreach 方法,但我遇到了数十行代码,这很难看且难以理解。我确信有一种优雅的方法。
如何返回List<TerminalLink>
仅包含与我的地图匹配的数据的修剪(即仅包含TerminalLinks
和ChannelGroupLinks
required ChannelLinks
)?
班级结构:
public class TerminalLink
{
public string TerminalName { get; set; }
public string TerminalType { get; set; }
public ChannelGroupLink[] ChannelGroups { get; set; }
}
public class ChannelGroupLink
{
public string GroupName { get; set; }
public int ItemType { get; set; }
public int SubType { get; set; }
public ChannelLink[] Channels { get; set; }
}
public class ChannelLink
{
public string ChannelName { get; set; }
public string PathName { get; set; }
public string DataType { get; set; }
public bool IsOutput { get; set; }
}
编辑以包括最新尝试:
public static List<TerminalLink> GetCompatibleChannelLinks(List<TerminalLinkMap> terminalLinkMaps, List<TerminalLink> asBuiltList)
{
List<TerminalLink> matching = new List<TerminalLink>();
var terminalsWithSomeMatchingChannelGroups = from terminal in asBuiltList
from tlm in terminalLinkMaps
where terminal.TerminalType == tlm.ItemSubTypeName
from cgsMaps in tlm.ChannelGroupsToLink
from cgs in terminal.ChannelGroups
where cgsMaps.IsLinkMatch(cgs.GroupName, cgs.ItemType, cgs.SubType)
select (
link: new TerminalLink()
{
TerminalName = terminal.TerminalName,
TerminalType = terminal.TerminalType
},
original: terminal, map: tlm
);
foreach (var possibleLink in terminalsWithSomeMatchingChannelGroups)
{
var linkCandidate = possibleLink.link;
var originalData = possibleLink.original;
var map = possibleLink.map;
foreach (var cgs in originalData.ChannelGroups)
{
foreach (var channel in cgs.Channels)
{
// WIP
}
}
}
}
编辑 2:包含 TerinalLinkMap
public class TerminalLinkMap
{
public string TerminalTypeName { get; set; }
public string ItemSubTypeName { get; set; } // Match on this.
public ChannelGroupToLink[] ChannelGroupsToLink { get; set; }
}
public class ChannelGroupToLink
{
public string GroupName { get; set; } // regex match is ok.
public int ItemType { get; set; }
public int SubType { get; set; }
public ChannelToLink[] Channels { get; set; }
public ChannelGroupToLink GetClone() => GetClone(this);
public bool IsLinkMatch(string groupName, int itemType, int subType)
{
return
GroupName == groupName
&& ItemType == itemType
&& SubType == subType;
}
}
public class ChannelToLink
{
public int ItemType { get; set; }
public string DataType { get; set; }
public int DataSizeInBits { get; set; }
public bool IsOutput { get; set; }
public ChannelToLink GetClone() => GetClone(this);
public bool IsLinkMatch(string dataType, bool isOutput)
{
return
DataType == dataType
&& IsOutput == isOutput;
}
public static ChannelToLink GetClone(ChannelToLink original) => new ChannelToLink()
{
ItemType = original.ItemType,
DataType = original.DataType,
DataSizeInBits = original.DataSizeInBits,
IsOutput = original.IsOutput
};
}
解决方案
没有必要加入。
尝试以下操作:
class Program
{
static void Main(string[] args)
{
List<TerminalLink> asBuiltList = new List<TerminalLink>();
List<TerminalLink> links = asBuiltList
.Select(x => new { TerminalLink = x, ChannelGroups = x.ChannelGroups.Where(y => y.IsLinkMatch("Apple", 123, 456)) })
.Where(x => x.ChannelGroups.Count() > 0)
.Select(x => new TerminalLink() { TerminalName = x.TerminalLink.TerminalName, TerminalType = x.TerminalLink.TerminalType, ChannelGroups = x.ChannelGroups.ToArray()})
.ToList();
}
}
public class TerminalLink
{
public string TerminalName { get; set; }
public string TerminalType { get; set; }
public ChannelGroupLink[] ChannelGroups { get; set; }
}
public class ChannelGroupLink
{
public string GroupName { get; set; }
public int ItemType { get; set; }
public int SubType { get; set; }
public ChannelLink[] Channels { get; set; }
public Boolean IsLinkMatch(string groupName, int itemType, int subType)
{
return (this.GroupName == groupName) && ( this.ItemType == itemType) && (this.SubType == subType);
}
}
public class ChannelLink
{
public string ChannelName { get; set; }
public string PathName { get; set; }
public string DataType { get; set; }
public bool IsOutput { get; set; }
}
}
推荐阅读
- reactjs - .Net Core 3.1 和 React (Redux-toolkit) 在 React 路由器硬刷新时获取“Cannot GET /*”
- mysql - Combine three tables with join an two with union
- prometheus - How to query a counter that moves slowly in an accurate way
- css - Color and background color not changing while hovered
- apache-kafka - Changing the log.dir path for Kafka
- android - I/Counters: exceeded sample count in FrameTime log
- python - How to place the nodes of a graph using pyVis following the coordinate system (latitude and longitude)?
- excel - 如何将电子表格重新组织成列表?
- python - Python: Convert class and under classes to dict
- c - 在堆上分配少于 4KB 的空间?