C# 为多对多和一对多关系实现逻辑类结构?
我有一组三个相互关联的类。具体来说,穿梭、停靠和路线C# 为多对多和一对多关系实现逻辑类结构?,c#,oop,C#,Oop,我有一组三个相互关联的类。具体来说,穿梭、停靠和路线 Stops can lie on multiple Routes and therefore Routes contain Stops. Shuttles can exist on one Route at a time, but Routes can contain multiple Shuttles. A Stop will always exist on at least one Route. A Shuttle may exist o
Stops can lie on multiple Routes and therefore Routes contain Stops.
Shuttles can exist on one Route at a time, but Routes can contain multiple Shuttles.
A Stop will always exist on at least one Route.
A Shuttle may exist on no Route (though this is avoidable by discarding any Shuttles that are off-Route).
我的问题是如何在逻辑上关联这三个类,以便访问它们中的任何一个都尽可能简单
一个类的每个实例都有一个唯一的ID(在它自己的类型中)可供引用,因此我将所有内容都存储在字典中,以便能够通过ID访问任何元素
我开始使用的关系使我很容易选择一条特定的路线,但因为站点和往返车都包含在路线的字典中。我必须知道停靠站或穿梭机所在的路线才能参考它,这是不可能的,因为我只有一个可用的路线列表,因此有必要迭代每条路线,直到找到正确的停靠站/穿梭机
我想出的每一个选择都会遇到类似的问题。我想出的最好的办法是
class Container
{
Dictionary<int, Shuttle> shuttles;
Dictionary<int, Route> routes;
}
class Shuttle
{
int shuttleId;
int routeId;
}
class Route
{
int routeId;
Dictionary<string, Stop> stops;
}
class Stop
{
string stopId;
}
类容器
{
字典穿梭机;
字典路径;
}
班车
{
羽毛球;
int routeId;
}
班级路线
{
int routeId;
字典停止;
}
班站
{
字符串stopId;
}
然而,这仅仅是最好的,因为此时代码的操作非常具体。它计算每个站点/路线组合的ETA,这可以通过迭代穿梭机并计算穿梭机到达当前路线上每个站点所需的时间来完成
不过,我还想在其他地方使用这些类,例如在地图显示上。在这里,此结构中断,因为我希望在选择站点时显示一个气球,显示站点链接到的路线。显然,我无法直接获取该信息,因为站点不知道路线。修改容器类,以提供获取给定站点的所有路线的方法
public static class Container
{
private static Dictionary<int, Shuttle> shuttles;
private static Dictionary<int, Route> routes;
/* Other stuff goes on to initialize shuttles and routes I assume */
public static List<Route> getRoutes(string stopId)
{
List<Route> stopRoutes = new List<Route>();
foreach (int myKey in routes.Keys)
{
foreach (string str in routes[myKey].stops.Keys)
{
if (routes[myKey].stops[str] == stopId)
{
stopRoutes.Add(routes[myKey]);
break;
}
}
}
return stopRoutes;
}
公共静态类容器
{
私有静态字典穿梭机;
私有静态字典路由;
/*我假设还有其他东西可以初始化穿梭机和路线*/
公共静态列表getRoutes(字符串stopId)
{
List stopRoutes=新列表();
foreach(路由中的int-myKey.key)
{
foreach(路由[myKey].stops.Keys中的字符串str)
{
if(路由[myKey].stops[str]==stopId)
{
添加(routes[myKey]);
打破
}
}
}
返回站路线;
}
如果您正在处理非常大的数据集,或者您可能会非常频繁地进行该调用,那么您可能需要比上面更高效的方法。例如,您将getRoutes方法设置为私有,并维护一个将StopID映射到路由列表的字典,并在添加新路由或新站点时更新它o避免在每次需要站点路线时调用getRoutes
我还假设您的应用程序只需要容器类的一个实例,因为它似乎只是所有往返/路线数据的容器。这里有一种方法。实体之间的双向引用确实需要一些维护代码来管理更改,但您可以轻松地从任何实例转到任何其他实例例如
// World knows about every entity in it.
// World cares not how entities are related to each other.
public class World
{
Dictionary<int, Shuttle> shuttles;
Dictionary<int, Route> routes;
Dictionary<int, Stop> stops;
}
public class Shuttle
{
Route CurrentRoute;
}
public class Stop
{
Dictionary<int, Route> Routes;
}
public class Route
{
Dictionary<int, Shuttle> Shuttles;
Dictionary<int, Stop> Stops;
}
我确实研究过做类似的事情,但我发现它被称为循环依赖,并且使它看起来普遍不受欢迎。我知道总是有例外,这是其中之一吗?你有循环关系,例如,我的路线站点的路线的穿梭机。如果你序列化这些类型,你必须t IsReference=true来处理循环,但除此之外,这没什么大不了的。@Mr.dimension-这确实是一个循环依赖,但如果你小心处理它,那就好了。这在.NET中是非常常见的做法。正如DavidB所说,“需要一些维护代码来管理更改”-你只需要小心,不要陷入无限的循环依赖停止->路线->停止->路线->停止->路线等的oop
from stop in World.routes[myRouteId].Stops.Values
from route in stop.Routes.Values
where route.Id != myRouteId
from shuttle in route.Shuttles
select shuttle;