【问题标题】:c# Design pattern related to Repositoryc# Repository相关的设计模式
【发布时间】:2026-01-18 13:50:02
【问题描述】:

我有一个存储库类说调用 FileRepository() 在 C# 托管层中工作。有一个方法调用 LoadRecordFromFile() 访问 C++ 非托管 COM DLL 以加载大量记录,如图:

LoadRecordFromFile()
{
     for (uint index = 1; index <= this.File.Count; index++)
     {
      // create new record object here
     }
}

记录对象中的信息稍后将用于生成 AnalysisViewModel 对象。因此,还有另一个 for 循环用于生成 AnalysisViewModel 对象的集合,然后才能在视图中用于显示。

问题在于第二个 for 循环使用了大量的加载时间。我试图通过在 LoadRecordFromFile() 中使用一个 for 循环替换两个 for 循环来优化加载时间。即在 FileRepository 类的 LoadRecordFromFile() 中的 for 循环中一起创建记录对象和 AnalysisViewModel() 对象。然而它打破了存储库设计模式的封装。 请有人建议如何重新设计两个类(AnalysisVeiwModel 和 FileRepository)以实现仅使用一个 for 循环来减少文件加载时间?谢谢

【问题讨论】:

    标签: c# design-patterns mvvm repository-pattern


    【解决方案1】:

    创建一个自定义枚举器,将 API 调用封装到 COM dll。

    首先声明您的收藏。集合只是创建枚举器的包装器:

    public class MyCustomCollection : IEnumerable<YouRecordType>
    {
        private readonly string _fileName;
    
        public MyCustomCollection(string fileName)
        {
            if (fileName == null) throw new ArgumentNullException(nameof(fileName));
            _fileName = fileName;
        }
    
        public IEnumerator<YouRecordType> GetEnumerator()
        {
            return new MyCustomEnumerator(_fileName);
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    

    .. 集合应由您的存储库返回。

    枚举器本身就是使用 COM 对象的类:

    public class MyCustomEnumerator : IEnumerator<YouRecordType>
    {
        private readonly string _fileName;
        private int _index;
        YouRecordType _current;
    
        public MyCustomEnumerator(string fileName)
        {
            _fileName = fileName;
            //open COM object here
        }
    
        public void Dispose()
        {
            //Dispose used COM resources.
        }
    
        public bool MoveNext()
        {
            //Read next row from the COM object
            var couldReadAnotherRow = true;
            _current = null; //comObject.Read(_index++); 
            return couldReadAnotherRow;
        }
    
        public void Reset()
        {
            //want to start over
        }
    
        public YouRecordType Current { get { return _current; } }
    
        object IEnumerator.Current
        {
            get { return Current; }
        }
    }
    

    您可以将其视为延迟加载的集合。即在调用它们之前不会加载任何行。

    因此,从您的存储库中返回该对象应该不会花费任何时间。而且您不必从一开始就预加载所有内容。

    可枚举的工作方式与任何其他集合一样。您可以使用yourCollection.ToList() 加载所有行或使用foreach(var yourType in yourCollection) 在每次迭代中加载新行。

    【讨论】:

      【解决方案2】:

      我会在您的视图模型中存储一组记录,而不仅仅是一个。

      所以你可以有一个AnalysisRecordsViewModel 一次从存储库中获取所有记录。

      如果您想在视图中显示或编辑单个记录,您可以使用第二个视图模型(例如 AnalysisViewModel)来显示单个记录。

      【讨论】: