. net c#在应用程序内传输数据的最佳对象
本文关键字:数据 最佳 对象 传输 应用程序 net | 更新日期: 2023-09-27 18:05:50
出于可读性和更好的可测试性的原因,我喜欢将我的应用程序代码组织成层-所以我有多个项目,每个项目有多个文件夹结构,每个文件夹可能有多个类,命名空间符合拓扑结构。这里没有什么特别的——大多数开发人员都以类似的方式构建代码。
在我的纯数据层中,我需要执行T-SQL Stored Procedure
来检索只读数据集-我只需要遍历行并读取列值。
在另一层,我需要执行行集上的各种数据转换(例如:组成一个配置文件提供给另一个应用程序)。
通常在我的数据层类中,我会使用SqlDataReader
来迭代行,提取列值,并内联执行数据转换。
但是我更喜欢把这个功能放到一个单独的类中。
所以我需要一个断开连接的数据传输容器。可能是DataSet
, DataTable
, DataView
, DataRowCollection
-但也许这些对我的目的来说是多余的。
对于传输只读数据的最佳类有哪些建议?
要做到这一点,您可以采用几种不同的策略:
- 使用LINQ to sql来避免双遍历行列表(第一次遍历填充数据表或pocos列表,第二次遍历转换)
- 定义一个idatattransformer接口,并将其传递给您的数据访问加载方法,并让该方法在从SqlDataReader加载数据时使用transformer来塑造数据。
- 使用实体框架自定义查询
选项1和选项3有很多资源,所以我在这里处理选项2。
假设您使用以下方法定义了一个ISomethingDataAccess
接口:
public interface ISomethingDataAccess
{
List<T> LoadAll<T>(Func<IDataReader, T> transformer);
}
transformer
参数将接受包含回调参数的参数,该回调参数将接受IDataReader
并返回T
类型的实例。
LoadAll<T>
方法是一个泛型方法,允许调用者确定将从IDataReader
创建的对象的类型,然后填充到将从该方法返回的List<T>
中。
在你的实现中你这样做:
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;
}
}
根据需要定制方法。现在您已经将转换关注点从数据访问类中分离出来了。
像这样使用:
public class SomethingBusiness()
{
public List<SomeTransformedThing> LoadAllSomethingsAsTransformedSomethings()
{
var returnList = this.dataAccess.LoadAll<SomeTransformedThing>
(reader=>new SomeTransformedThing()
{
// ... transform data from reader here
});
return returnList;
}
}