• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

OOP数据结构来表示由两个外键索引的表

c/c++ 来源:Alain 4次浏览

我一直负责将“表驱动”程序转换为面向对象的程序。过去一切都是通过在内存中创建大型表来完成的,添加和删除行和列并将所有内容解析为字符串。这非常可怕。这些表格直接反映了一切都被存储的底层数据库的结构。OOP数据结构来表示由两个外键索引的表

对于这个问题,我有Layer对象,约100个属性,我有Event对象,约20多个属性。然后我为每个Layer/Event对设置一组约10个计算值。这些存储为第三个表,其中外键指向其他每个表。

我想创建一个适当的面向对象类来存储这些数据,并像在字典中那样快速地访问值。

我首先想到的是指数在字典中的结果,但我觉得它的使用是不直观:

struct EventLayerResult { Decimal sum = 0; Long events = 0; Decimal average; ...} 
//Performing Calculations 
Dictionary<Tuple<Event,Layer>, EventLayerResult> _EventLayerResults ...; 
foreach(Event evt in _Events) 
    foreach(Layer lyr in _Layers) 
     EventLayerResult elr = newLayerLosses[Tuple.Create(evt, lyr)]; 
     elr.sum += currentValue; 
     elr.events += 1; 
     elr.average += elr.Sum/elr.Events; 
     etc... 
//Using results 
EventLayerResult temp = _EventLayerResults.TryGetValue(Tuple.Create(evt, lyr)) 
someLoss = temp == null ? 0 : temp.expectedLoss; 

我不喜欢打电话Tuple.Create或创建新实例的想法每次我创建一个值时,临时对象。此外,与表不同,如果我想在UI中绑定这个表,我不能只绑定到Field =“Layer”,Field =“Event”,Field =“Loss”等,我必须拿出复杂的绑定表达式提取Key.Layer,Key.Event,Value.Loss等。因此,我想避免这样的数据结构。

我可以将它包装在一个对象中,该对象可以轻松地查找事件/图层组合的每个值,但我不相信我应该为每个计算属性创建一个“get”方法,以便我可以使用它是这样的:

thisSum = _EventLayerResults.getSum(evt, lyr); 
thisEvent = _EventLayerResults.getExpectedLoss(evt, lyr); 

我也想结合包含在这样的结构导致的完整列表是不可能的。

我的最后一个想法(一个我认为是最接近的解决方案,我必须使用)与所有字段的对象/结构的简单集合,我需要参考:

class EventLayerResult { Event oevent; Layer layer; Decimal sum; Long events...} 
ObservableCollection<EventLayerResult> _EventLayerResults = .... 
_EventLayerResults.Add(new EventLayerResult(){ oevent = evt, layer = lyr }); 

这是超级容易绑定到,但问题是这个集合上没有’索引’。我正在寻找O(Nevts * Nlyrs)时间来查找特定的事件/图层结果,除非我开始添加所有这些额外的行李,比如监视集合的自定义包装类添加事件并在字典中索引集合项等

我无法想象其他人每次都想通过两个外键索引将一个简单的表转换为对象模型时经历所有这些。有没有我不知道的标准方法或数据结构可以使这类数据集简单易用?


===========解决方案如下:

我到目前为止所提出的最佳解决方案是使用字典来包装外键上的集合和索引,就像我在OP中建议的那样。好像很多工作,但:

public class EventGroupIDLayerTuple : Tuple<Int32, Layer> 
{ 
    public EventGroupIDLayerTuple(Int32 EventGroupID, Layer Layer) : base(EventGroupID, Layer) { } 
    public Int32 EventGroupID { get { return this.Item1; } } 
    public Layer Layer { get { return this.Item2; } } 
} 
public class EventGroupLayerResult 
{ 
    public Int32 EventGroupID { get; set; } 
    public Layer Layer { get; set; } 
    //Computed Values 
    public Decimal Sum { get; set; } 
    public Decimal Average { get; set; } 
    //... 
} 

/// <summary>ObservableCollection of computed EventGroup/Layer results that are also indexed 
/// in a dictionary for rapid retrieval.</summary> 
public class EventGroupLayerResultCollection : ObservableCollection<EventGroupLayerResult> 
{ 
    Dictionary<EventGroupIDLayerTuple, EventGroupLayerResult> _Index = 
     new Dictionary<EventGroupIDLayerTuple,EventGroupLayerResult>(); 

    public EventGroupLayerResultCollection() : base() { } 

    /// <summary>Will return the result for the specified eventGroupID/Layer 
    /// combination, or create a new result and return it.</summary> 
    public EventGroupLayerResult this[Int32 eventGroupID, Layer layer] 
    { 
     get 
     { 
      EventGroupLayerResult retval; 
      if(!_Index.TryGetValue(new EventGroupIDLayerTuple(eventGroupID, layer), out retval)) 
      { 
       retval = new EventGroupLayerResult() { EventGroupID = eventGroupID, Layer = layer }; 
       this.Add(retval); 
      } 
      return retval; 
     } 
    } 

    public bool Contains(Int32 eventGroupID, Layer layer) 
    { 
     return _Index.ContainsKey(new EventGroupIDLayerTuple(eventGroupID, layer)); 
    } 

    #region Index Maintenance 
    protected override void ClearItems() 
    { 
     _Index.Clear(); 
     base.ClearItems(); 
    } 
    protected override void InsertItem(int index, EventGroupLayerResult item) 
    { 
     _Index.Add(new EventGroupIDLayerTuple(item.EventGroupID, item.Layer), item); 
     base.InsertItem(index, item); 
    } 
    protected override void RemoveItem(int index) 
    { 
     _Index.Remove(new EventGroupIDLayerTuple(this[index].EventGroupID, this[index].Layer)); 
     base.RemoveItem(index); 
    } 
    protected override void SetItem(int index, EventGroupLayerResult item) 
    { 
     _Index.Remove(new EventGroupIDLayerTuple(this[index].EventGroupID, this[index].Layer)); 
     _Index.Add(new EventGroupIDLayerTuple(item.EventGroupID, item.Layer), item); 
     base.SetItem(index, item); 
    } 
    #endregion 
} 

此代码让我迅速地集合在创建/访问/修改的元素,像这样:

eventGroupLayerResults[evt.GroupID, lyr].Sum += value; 

,同时还允许我轻松地收集绑定到UI。

更好的解决方案仍然会被赞赏,虽然,因为我不得不重写一堆ObservableCollection方法来做到这一点。


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)