【问题标题】:Is it ok to use reflection to get property names and values in a base class?可以使用反射来获取基类中的属性名称和值吗?
【发布时间】:2009-09-10 18:52:20
【问题描述】:

我正在使用以下代码将对象及其所有属性保存到数据库中。它使我不必在每个业务对象中创建保存方法。我的基类中的代码是:

    public void Save()
    {
        List<SqlParameter> Params = new List<SqlParameter>();
        foreach (PropertyInfo Property in this.GetType().GetProperties())
        {
            if (Property.CanRead)                
                Params.Add(new SqlParameter(Property.Name,Property.GetValue(this,null)));                
        }
        Execute<int>(SaveProcedure, Params.ToArray());        
    }

这是一个好习惯还是我最好不要使用反射并在我创建的每个对象中创建一个保存方法?

任何其他想法或建议表示赞赏,谢谢!

【问题讨论】:

  • 如果您的数据库没有与对象的属性名称匹配的字段,您可能会遇到一些问题。
  • 感谢大家的快速回复。我将研究 LinqToSql 并完全避免这种情况。

标签: .net reflection inheritance


【解决方案1】:

您似乎正在创建自己的基本ORM。您是否考虑过使用专为 .NET 框架编写的成熟映射器来执行此任务,例如 LinqToSqlNHibernate

【讨论】:

    【解决方案2】:

    我通常会将其归类为不好的,或者至少是糟糕的做法。反射成本有几个程度,其中最高的成本是调用(即调用方法、获取或设置属性/字段值等)。通过像这样通过反射保存对象,您会产生非常高的成本。比直接访问属性要慢几个数量级。

    抛开反射成本不谈,从意图的角度来看,这通常也是不好的做法。您正在保存所有属性...但是当有人创建具有未映射到数据库表列的属性的派生类型时会发生什么?您应该使您的保存方法虚拟或抽象,并根据每个实体的需要实现/扩展该方法。

    最后一点......直接在这样的实体上处理储蓄是一场等待发生的真正的维护噩梦。当您将关注点和职责混合到一个类中时,您会遇到很多麻烦。制作实体/业务对象 POCO(普通的旧 clr 对象)并编写显式数据映射器会好得多。这将分离您的关注点,并将每个类的职责减少到尽可能少。丰富的、自我保存(和加载)的实体很方便,但主要是一个梦想。在实践中,鉴于您将面临更大的维护困难,它们通常不值得它们提供的微小好处。

    我建议查看 OR 映射器(LINQ to SQL、nHibernate、Entity Framework v4 等)。当您需要加载、保存或删除实体时,OR 映射器会自动为您生成 SQL。当您不使用 OR 映射器时,它们可以消除大量所需的额外编码,并支持更具适应性的代码库。

    【讨论】:

      【解决方案3】:

      作为一个工作严重依赖反思的人,我认为这并不合适。但是,您应该仔细考虑它的权衡。使用反射可以让你退出编译时检查,这意味着没有早期的错误检测。所以如果你真的认为反射可以帮助你更好地管理代码并且你不介意它的性能,那么使用反射应该不是问题。

      另外请注意,每次使用反射时,请确保创建足够的测试来帮助您及早发现问题。

      只是一点点。

      【讨论】:

        【解决方案4】:

        反射实际上只用于程序分析。使用它会对程序的性能和可证明性产生非常严重的副作用。这并不意味着在生产应用程序中不存在适合反射的情况,但我认为这不是其中一种情况。对于数据库中的存储,我建议查找序列化。

        【讨论】:

          【解决方案5】:

          从设计的角度来看,我认为为每个类单独保存会更灵活。这将允许选择您相同的属性并允许在存储到数据库之前进行必要的预处理(即无法保存复杂对象本身。

          【讨论】:

            猜你喜欢
            • 2011-10-02
            • 1970-01-01
            • 1970-01-01
            • 2011-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-10
            • 1970-01-01
            相关资源
            最近更新 更多