c# - 有没有通用的方法来填充数据库中的对象?

标签 c# .net generics

在我的软件中有一个常见的模式,其中完成数据库查询并根据该查询创建对象列表,其中对象是从 SqlDataReader 构造的。

例如:

public List<Authorization> ReadAuthorizations() {
  List<Authorization> authorizations = new List<Authorization>();

  using (SqlConnection connection = GetConnection(mConnString)) {
    using (SqlDataReader authReader = CmdFactory.Instance.ReadAuthorizations(connection))                                   {
      while (authReader.Read()) {
        Authorization auth = new Authorization(authReader);
        authorizations.Add(auth);
      }
    }
 }

 return authorizations;
}

您可以将 Authorization 替换为任何类型的对象,但每次的模式都是相同的。唯一的变量是对象类型和用于查询数据库的函数。

List<Authorization> ReadAuthorizations()
List<Login> ReadLogins()
List<Batch> ReadBatches()
// etc

现在我在想这只是为了一个通用函数而尖叫,我想出了这个:

public List<T> Read<T>(Func<SqlConnection, SqlDataReader> func) where T : new()
{
    List<T> objects = new List<T>();

    using (SqlConnection connection = GetConnection(_ropsString))
    {
        using (SqlDataReader reader = func(connection))
        {
            while (reader.Read())
            {
                T obj = new T(reader);
                objects.Add(obj);
            }
        }
    }

    return objects;
}

这几乎可以工作,除了要构造的对象不允许采用参数,VS2k10 说:

'T': cannot provide arguments when creating an instance of a variable type

有没有办法解决这个问题,让变量类型可以获得构造函数参数?

最佳答案

给这只猫剥皮的方法有很多种,但为了让您继续朝着您选择的探索方向前进:

使用通用约束指定 where T : IPopulateFromReader, new() 并将读取器参数移动到方法调用中:

T obj = new T();
obj.PopulateFromReader(reader);
objects.Add(obj);

interface IPopulateFromReader
{
    void PopulateFromReader(IDataReader reader);
}

更严肃地说,也许可以看看 ORM 解决方案,例如:

不胜枚举。关键是,它们成功地提供了对数据库访问的抽象并减轻了阻抗不匹配问题,使您可以专注于域模型和业务逻辑而忽略样板 DAL 代码。通常还支持管理数据库模式(尽管对此的支持因库/框架的重点而异)。

关于c# - 有没有通用的方法来填充数据库中的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19561664/

相关文章:

c# - 泛型类中有歧义/冲突的构造函数

c# - Environment.TickCount 与 DateTime.Now

swift - 无法为泛型类型的子类调用初始值设定项

c++ - 具有通用输入参数的函数

java - 非泛型类扩展泛型类是什么意思

c# - 并非所有路径都返回一个值。 - 可选返回?

c# - 多个单独的正则表达式

c# - 如何使用 configurationManager 从 .Net 4.0 中的 App.config 读取值?

c# - 在 C# 中,有没有一种方法可以在不循环的情况下将数组转换为 Stack<T>?

c# - 使用 WebClient 时如何强制执行 SSL?