与Repository相关的c#设计模式
c# Design pattern related to Repository
我有一个存储库 class 说调用 FileRepository() 在 C# 托管层中工作。有一个方法调用 LoadRecordFromFile() 访问 C++ 非托管 COM DLL 来加载大量记录,如图:
LoadRecordFromFile()
{
for (uint index = 1; index <= this.File.Count; index++)
{
// create new record object here
}
}
记录对象中的信息稍后将用于生成AnalysisViewModel对象。因此,还有一个for循环用于生成AnalysisViewModel对象的集合,然后才能在View中用于显示。
问题是第二个 for 循环使用了大量的加载时间。我试图通过在 LoadRecordFromFile() 中使用一个 for 循环替换两个 for 循环来优化加载时间。即在 FileRepository class 中的 LoadRecordFromFile() 的 for 循环中同时创建记录对象和 AnalysisViewModel() 对象。但是它打破了存储库设计模式的封装。
请有人建议如何重新设计两个 classes(AnalysisVeiwModel 和 FileRepository)以实现仅使用一个 for 循环来减少文件加载时间?谢谢
我会在您的视图模型中存储一组记录,而不仅仅是一个。
所以你可以有一个 AnalysisRecordsViewModel
一次性从存储库中获取所有记录。
如果您想在视图中显示或编辑单条记录,您可以使用第二个视图模型,例如 AnalysisViewModel
来显示单条记录。
创建一个自定义枚举器,将 API 调用包装到 COM dll。
首先声明您的 collection。 collection 只是创建枚举器的包装器:
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();
}
}
.. collection 应该由您的存储库返回。
枚举器本身是使用 COM object:
的 class
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; }
}
}
您可以将其视为延迟加载 collection。即在调用它们之前不会加载任何行。
因此从您的存储库中返回 object 根本不需要时间。而且您不必从一开始就预加载所有内容。
可枚举的工作方式与其他任何一样 collection。您可以使用 yourCollection.ToList()
加载所有行或 foreach(var yourType in yourCollection)
在每次迭代中加载新行。
我有一个存储库 class 说调用 FileRepository() 在 C# 托管层中工作。有一个方法调用 LoadRecordFromFile() 访问 C++ 非托管 COM DLL 来加载大量记录,如图:
LoadRecordFromFile()
{
for (uint index = 1; index <= this.File.Count; index++)
{
// create new record object here
}
}
记录对象中的信息稍后将用于生成AnalysisViewModel对象。因此,还有一个for循环用于生成AnalysisViewModel对象的集合,然后才能在View中用于显示。
问题是第二个 for 循环使用了大量的加载时间。我试图通过在 LoadRecordFromFile() 中使用一个 for 循环替换两个 for 循环来优化加载时间。即在 FileRepository class 中的 LoadRecordFromFile() 的 for 循环中同时创建记录对象和 AnalysisViewModel() 对象。但是它打破了存储库设计模式的封装。 请有人建议如何重新设计两个 classes(AnalysisVeiwModel 和 FileRepository)以实现仅使用一个 for 循环来减少文件加载时间?谢谢
我会在您的视图模型中存储一组记录,而不仅仅是一个。
所以你可以有一个 AnalysisRecordsViewModel
一次性从存储库中获取所有记录。
如果您想在视图中显示或编辑单条记录,您可以使用第二个视图模型,例如 AnalysisViewModel
来显示单条记录。
创建一个自定义枚举器,将 API 调用包装到 COM dll。
首先声明您的 collection。 collection 只是创建枚举器的包装器:
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();
}
}
.. collection 应该由您的存储库返回。
枚举器本身是使用 COM object:
的 classpublic 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; }
}
}
您可以将其视为延迟加载 collection。即在调用它们之前不会加载任何行。
因此从您的存储库中返回 object 根本不需要时间。而且您不必从一开始就预加载所有内容。
可枚举的工作方式与其他任何一样 collection。您可以使用 yourCollection.ToList()
加载所有行或 foreach(var yourType in yourCollection)
在每次迭代中加载新行。