将领域模型转换为DataTable以简化ObjectDataSource的使用

在WinForms应用程序中使用对象关系映射(ORM)模型已经有一段时间了。最近,需要为ASP.NET应用程序开发,很快就对ObjectDataSource感到非常沮丧。不想就DataSet和集合之间进行辩论。简而言之,使用强类型集合。

当使用非平面(层次化)领域模型时,无法绑定到复杂属性。例如,在下面的领域模型中,需要在课程列表中显示Instructor的FullName,然后能够编辑它。然而,虽然可以绑定到Instructor,但它会显示Person的toString()方法中的任何内容。这对于显示来说是可以的,但编辑呢?可以实施IConvertible,但不需要在表示层之外的任何地方使用这个功能。因此,让使用适配器设计模式将对象集合(或单个对象)适配到DataTable

这种方法还带来了许多其他优势。ObjectDataSource在没有大量管道的情况下不会很好地排序或分页。当绑定到DataTable时,它会本地处理,因此不需要编写额外的代码。

使用代码

由于Course没有显示属性"InstructorId"、"InstructorFullName"或"AvailableSlots",可以将它们混合到数据类型中,就好像它们是类的一部分一样。像Ruby和Python这样的动态语言允许在对象级别上这样做,从而消除了在转换中这样做的需要。C#3(和VB9)有所谓的扩展方法,但到目前为止还没有提到扩展属性(数据绑定需要)。

public static DataTable FindAll() { DataTableAdapter dta = new DataTableAdapter(); dta.AddColumn("InstructorId", typeof(string), delegate(Course c) { return c.Instructor.Id; }); dta.AddColumn("InstructorFullName", typeof(string), delegate(Course c) { return c.Instructor.FullName; }); dta.AddColumn("AvailableSlots", typeof(string), delegate(Course c) { return c.MaxStudents - c.Students.Count; }); return dta.GetDataTable(CourseService.FindAll()); }

潜在问题

这里大量使用了反射。这可能会导致一些性能问题,具体取决于使用的对象基础有多大。

源代码

PropertyInfo[] pi = typeof(T).GetProperties(); Type piType; for (int i = 0; i < pi.Length; i++) { piType = pi[i].PropertyType; if (piType.IsGenericType && piType.GetGenericTypeDefinition() == typeof(Nullable<>)) piType = Nullable.GetUnderlyingType(piType); dt.Columns.Add(new DataColumn(pi[i].Name, piType)); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485