.NET C# 在应用程序内传输数据的最佳对象

.NET C# best object to transport data within application

出于可读性和更好的可测试性的原因,我喜欢将我的应用程序代码组织成层 - 所以我有多个项目,每个项目都有多个文件夹结构,每个文件夹可能有多个 classes,带有命名空间符合拓扑。这里没什么特别的 - 大多数开发人员以类似的方式构建代码。

在我的纯数据层中,我需要执行 T-SQL Stored Procedure 来检索只读数据集 - 我只需要遍历行并读取列值。

在另一层中,我需要对行集执行各种数据转换(示例:编写要提供给另一个应用程序的配置文件)。

通常在我的数据层 class 我会使用 SqlDataReader 迭代行,提取列值,并执行内联数据转换。

但我更愿意将此功能分解为单独的 class。

所以我需要一个断开连接的数据传输容器。可能性是 DataSetDataTableDataViewDataRowCollection - 但也许这些对我的目的来说有点矫枉过正。

有哪些最佳class传输只读数据的建议?

您可以采用几种不同的策略来执行此操作:

  1. 使用 LINQ to sql 避免重复行列表(第一次填充数据表或 pocos 列表,第二次进行转换)
  2. 定义一个 IDataTransformer 接口并将其传递给您的数据访问加载方法,并让该方法在从 SqlDataReader 加载数据时使用转换器来调整数据。
  3. 将 Entity Framework 用于自定义查询。

选项 1 和选项 3 有很多资源,所以我将在这里处理选项 2。

假设您使用以下方法定义了一个 ISomethingDataAccess 接口:

public interface ISomethingDataAccess
{
    List<T> LoadAll<T>(Func<IDataReader, T> transformer);
}

transformer 参数将接受包含回调的参数,该回调将接受 IDataReader 和 return 类型 T 的实例。

LoadAll<T> 方法是一种通用方法,它允许调用者确定将从 IDataReader 创建的对象的类型,然后填充到 List<T> return从方法中编辑。

在你的实现中,你会做这样的事情:

public class SqlSomethingDataAccess : ISomethingDataAccess
{
    public List<T> LoadAll<T>(Func<IDataReader, T> transformer)
    {
        // ... Setup connection and command, etc ...
        var returnList = new List<T>();
        var reader = command.ExecuteReader();  // <- from setup steps above
        while(!reader.MoveNext())
        {
            returnList.Add(transformer(reader));
        }
        return returnList;
    }
}

根据您的需要自定义方法。现在您已经将转换问题分离到数据访问之外 class.

像这样使用它:

public class SomethingBusiness()
{
    public List<SomeTransformedThing> LoadAllSomethingsAsTransformedSomethings()
    {
        var returnList = this.dataAccess.LoadAll<SomeTransformedThing>
        (reader=>new SomeTransformedThing()
        {
             // ... transform data from reader here
        });

        return returnList;
    }
}