简体   繁体   English

与存储库相关的C#设计模式

[英]c# Design pattern related to Repository

I have a repository class say call FileRepository() working in the C# managed layer. 我有一个存储库类,说可以在C#托管层中调用FileRepository()。 There is a method call LoadRecordFromFile() which access to the C++ unmanaged COM DLL to load a large amount of records, as shown : 有一个调用LoadRecordFromFile()的方法,该方法可以访问C ++非托管COM DLL来加载大量记录,如下所示:

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

The information in the record object will later used to generate AnalysisViewModel object. 记录对象中的信息以后将用于生成AnalysisViewModel对象。 Thus, There is another for loop used to generate a collection of AnalysisViewModel objects before it can be used in the View for display. 因此,还有一个for循环可用于生成AnalysisViewModel对象的集合,然后再将其用于View中进行显示。

The problem is that the second for loop is using vast amount of loading time. 问题在于第二个for循环正在使用大量的加载时间。 I am trying to optimise the loading time by replacing two for loop by using one for loop in the LoadRecordFromFile(). 我试图通过在LoadRecordFromFile()中使用一个for循环替换两个for循环来优化加载时间。 ie create both record object and AnalysisViewModel() object together in the for loop in LoadRecordFromFile() in FileRepository class. 即在FileRepository类的LoadRecordFromFile()中的for循环中一起创建记录对象和AnalysisViewModel()对象。 However It breaks the encapsulation of repository design pattern. 但是,它破坏了存储库设计模式的封装。 Please would someone propose how to redesign the two classes (AnalysisVeiwModel and FileRepository)to achieve using only one for loop to reduce the file loading time ? 请有人提出如何重新设计两个类(AnalysisVeiwModel和FileRepository)以仅使用一个for循环来减少文件加载时间的方法吗? Thank you 谢谢

I would store a collection of the records in your view model instead of just one. 我将在您的视图模型中存储记录的集合,而不仅仅是一个。

So you could have a AnalysisRecordsViewModel which gets all records from the repository at once. 因此,您可以拥有一个AnalysisRecordsViewModel ,它可以一次从存储库中获取所有记录。

If you want to display or edit a single records in your view, your might use a second view model like AnalysisViewModel to display a single record. 如果要在视图中显示或编辑单个记录,则可以使用第二个视图模型(如AnalysisViewModel来显示单个记录。

Create a custom enumerator wrapping the API calls to the COM dll. 创建一个自定义枚举器,将API调用包装到COM dll。

Start by declaring your collection. 首先声明您的收藏。 The collection is just a wrapper to create a enumerator: 该集合只是用于创建枚举器的包装器:

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();
    }
}

.. the collection should be returned by your repository. ..集合应由您的存储库返回。

The enumerator itself is the class that uses the COM object: 枚举器本身就是使用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; }
    }
}

You can see it as a lazy loaded collection. 您可以将其视为延迟加载的集合。 ie no rows are loaded until they are being called. 即在调用它们之前,不会加载任何行。

Thus returning that object from your repository should take no time at all. 因此,从您的存储库中返回该对象完全不需要花费时间。 And you do not have to preload everything from start. 而且您不必从一开始就预加载所有内容。

The enumerable works just like any other collection. 可枚举的工作方式与其他任何集合一样。 You can use yourCollection.ToList() to load all rows or foreach(var yourType in yourCollection) to load a new row in every iteration. 您可以使用yourCollection.ToList()加载所有行,或使用foreach(var yourType in yourCollection)加载每次迭代中的新行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM