我使用以下代码将对象及其所有属性保存到db。它使我不必在每个业务对象中创建一个save方法。我的基类中的代码是:
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());
}
这是一个很好的做法,还是我最好不要在我创建的每个对象中使用反射和创建保存方法?
感谢任何其他想法或建议,谢谢!
答案 0 :(得分:7)
您似乎正在创建自己的基本ORM。您是否考虑过使用专门为.NET框架编写的任何完全成熟的映射器来执行此任务,例如LinqToSql或NHibernate?
答案 1 :(得分:1)
我通常会认为这是一种不好的,或者至少是差的做法。反射成本有几度,最高成本是调用(即调用方法,获取或设置属性/字段值等)通过这样的反射保存对象,会产生非常高的成本。比直接访问属性要慢几个数量级。
除了反思成本之外,从意图的角度来看,这通常也是不好的做法。您正在保存所有属性...但是当有人创建具有不映射到数据库表列的属性的派生类型时会发生什么?您应该将save方法设置为virtual或abstract,并根据需要为每个实体实现/扩展该方法。
最后一点......处理直接存储在像这样的实体上是一个真正的维护噩梦等待发生。当你将关注点和责任混合到一个单独的课程中时,你要求一个很麻烦的地狱。制作实体/业务对象POCO(普通的旧clr对象)和编写显式数据映射器会更好。这将分离您的顾虑,并尽可能减少每个班级的责任。丰富,自我保存(和加载)实体很方便,但主要是梦想。在实践中,鉴于您将面临更大的维护困难,它们通常不值得提供它们所带来的微小好处。
我建议查看OR映射器(LINQ to SQL,nHibernate,Entity Framework v4等)或者当您需要加载,保存或删除实体时,mappers会自动为您生成SQL。当您不使用OR映射器时,它们可以消除大量额外的编码,并支持更具适应性的代码库。
答案 2 :(得分:0)
作为一名工作严重依赖反思的人,我认为这不合适。但是,你应该仔细考虑它的权衡。使用Reflection选择退出编译时检查,这意味着没有早期错误检测。因此,如果你真的认为反射可以帮助你更好地管理代码而你不介意它的性能,那么使用反射应该不是问题。
另一个注意事项,每次使用反射时都要确保您创建足够的测试来帮助您尽早发现问题。
只是一个。
答案 3 :(得分:0)
反射实际上仅用于程序分析。使用它对程序的性能和可证明性有非常严重的副作用。这并不意味着在生产应用中没有适合反射的情况,但我不认为这是其中一种情况。对于数据库中的存储,我建议查找序列化。
答案 4 :(得分:0)
从设计的角度来看,我认为为每个班级分别保存会更灵活。这将允许您选择相同的属性并允许在存储到DB之前进行必要的预处理(即复杂对象本身无法保存。