数据绑定 .NET 日程控件





0/5 (0投票)
将日程控件绑定到数据库的最佳方法是什么? 通常,响应会侧重于所需的实现;然而,业务规则可以用来定义战略性实现。本期产品展示将使用仓库发货和泊位调度作为隐喻来探讨该主题。
查看
仓库发货框架 (dbiWSF) 是 DBI 的一款综合性产品。该框架产品的起源源于与 Solutions Schedule for .NET 和 Studio Controls for .NET 相关的数据库绑定练习。我们收到的最常见问题之一是“将 dbiSchedule 控件和 dbiDayView 控件绑定到数据库的最佳方法是什么?以及最佳的实现结构是什么?”我们的初步回答通常侧重于用户如何使用这些控件。在使用日程控件时,需要设想三种主要结构——地点、联系人和任务。一旦建立好结构,下一个任务就是如何将约会附加到这些项目上。
在与我们的开发人员社区讨论组件使用和数据绑定过程时,很明显,“一刀切”的方法无法提供回答问题所需的细节,并且在这种方法中将使用的概念过于笼统。
借鉴我们内部的专业知识——我们项目团队的首席开发人员,在以前有几年担任一家木材场的系统管理员的经验,并且之后又有几年在一家软件开发团队工作的经验,该团队曾创建了一个非常复杂的发货和接收应用程序。我们的另一位关键员工之前在一家完全集成的仓库发货和接收系统中担任过分析师/首席开发人员。利用这些内部专业知识的集合,我们开始基于发货管理的概念,为数据绑定和使用问题打造独特的解决方案。我们的目标演变为提供一个基于发货和接收概念的框架,该框架最终将面向开发人员的各种编码和数据管理需求,所有这些都在 Solutions Schedule for .NET 和 Studio Controls for .NET (dbiDayView) 的上下文中。
随着框架开发的推进,人们发现开发人员无需经历完整的应用程序范围和定义过程,就能快速构建企业级解决方案。为了认证商业产品,我们自己经历了这些详细的过程,那么为什么不将其包含在内呢?没有理由让其他人重新发明轮子。这些过程现在已作为框架的一部分打包。
我们最初专注于数据绑定层,毕竟这是项目的驱动力,但随着项目进展,它实际上只成了整个框架解决方案的一部分。用户界面层也变得非常重要。凭借 DBI 行业公认的 UI 设计控件,将 Studio Controls for .NET 中的许多组件整合进来,以构建完整的用户界面层,这是顺理成章的。现在,我们最初问题的答案正在逐步清晰:如何最好地将两个不同的日程控件进行数据绑定。框架概念作为交付解决方案的媒介,效果非常好。
当然,一路上也遇到了一些障碍。从项目开始,开发团队就有一个主要痛点,那就是能够将业务规则对象化,从而赋予框架真实的生命力。这个痛点演变成了一个严谨的过程,仔细地界定了将发货和接收业务规则普遍应用于框架的仓库发货对象的方法。经过仔细的权衡,现在可以从任何 UI 或外部应用程序调用这些规则。结果出人意料地简单,但却极其强大、灵活且可重用。
术语
dbi 仓库发货调度框架 (dbiWSF) 是一个源代码产品,包含三个单独的 .dll 文件,我们亲切地称之为层。核心的 dbiWSF .dll 包含数据绑定层和实际的 dbiWSF 对象层。第二层是业务规则层。该层封装了一系列业务规则,这些规则可以应用于 dbiWSF 对象上的任何创建/更新/删除方法。最后是 UI 层,其中包含基于 Solutions Schedule for .NET 和 Studio Controls for .NET 组件的自定义控件;我们对这些自定义控件进行了封装并暴露了通用事件和方法。对于熟悉 DBI 组件软件产品的用户来说,这种封装的一个例子是将我们的特定事件应用于 dbiWSF 对象。因此,与其说是一个时间轴拖动之前的事件,不如说我们现在暴露了一个发货拖动之前的事件。这样,无论使用哪个 UI 控件,都可以使用相同的代码块。对于 dbiScheduleTimeBar 和 dbiDayView 控件中的 dbi 约会,发货移动之前的事件是相同的。这个概念可以进一步应用于其他控件,包括 Silverlight List 控件或 ASP.Net 控件。
仓库调度框架利用了 Solutions Schedule for .NET Enterprise Edition 和 Studio Controls for .NET 产品中的几个 DBI 组件。
应用程序设计
A) dbiWSF 对象层和数据绑定层
dbiWSF 的核心是 `dbiWSFObject` 层。该层与数据绑定层结合,负责加载和显示数据。在其核心,`dbiWSFObject` 更改时会自动触发相应的数据库更新(对于偏好批量处理的用户,可以禁用此功能)。对象的布局可以封装在 dbiWSFSchedule 控件中。
继承关系如下:
dbiWSFMainObjects - a parent container object usually defined in a module or global variable WarehouseObjects collection (1 to many) LoadingDocks collection (1 to many) -> also a collection of accepted CargoTypes) Shipments collection (0 to many) OrderHeaders collection (0 to many) -> Point of Integration for POS/Shipping system OrderDetails collection (0 to many) -> Point of Integration for POS/Shipping system
- `dbiWSFExceptions` - 一系列异常对象,指示 1 到多个装卸区不可用(这些在 dbiWSFSchedule(米色区域)和 dbiWSFDayView 中显示为自定义区域)。
- `dbiWSFCargoTypes` - 不同货物类型 (CargoTypes) 的集合,这些可以应用于装卸区和订单详情。
如前所述,对象连接到数据绑定层。这段代码将 ADO.NET 数据库调用集成到对象本身。用于绑定数据的方法以及 UI 层中的示例详细说明了数据库层如何映射到对象,从而实现双部分数据库编码。只需向表中添加一列,并在 `dbiWSFObject` 中添加一个相应的属性,两者即可同步。使用反射,默认的维护表单将自动检测更改,而无需为 said 属性编写特定的 UI 控件。简单来说,如果我想在数据库中添加一个 Address 列,我会在表中添加该列,然后在我的 `LoadingDock` 对象中添加相应的属性。其余的由控件处理。这是一个突出显示此概念的视频。
dbiWSF 产品附带干净版和演示版数据库。我们包含独立的 MSSQL 数据库表、Access 数据库以及一个 PDF 文件,其中包含数据库布局,供使用其他数据库类型的用户参考。源代码有三个级别的数据库设计。标准数据库方法基本上是按照对象结构中使用的方式加载数据,这种方法易于阅读但速度慢。第二种方法 InMemory 使用 LINQ to Objects 和 For..Each 循环先加载数据,然后将其映射到对象。这是一种非常快速的方法,但编码起来有点复杂。最后,我们提供第三种方法 Custom,这是针对使用存储过程、复杂查询或非 ADO.NET 数据访问(XML、ODBC)的空模板代码。这为开发人员在处理 dbiWSF 产品的其他方面时提供了最灵活的选择。例如,您可以将 XML 文档映射到 WSF 对象,然后依赖于代码中编写的报告、业务规则和 UI 层,但开发人员将负责文件更新和 CRUD 操作。
连接 dbiWSF 对象到 AccessDatabase、创建业务规则对象和上下文菜单对象的代码。
'Module code to attach to the database and create the business rules and context menu.
Module modMain
Public myWSFObjects As New dbiWSF.FrameworkObjects.objWSFObjects(
dbiWSF.Databinding.ConnectionTypes.OLEDatabase, _
dbiWSF.Databinding.DataBindingMethods.InMemory, _
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source = WSFOleDB.accdb")
'Business Rules
Public myBusinessRules As New dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects(
myWSFObjects)
'Create a context menu.
Public WithEvents myWSFContextMenu As New dbiWSF.ControlLibrary.dbiWSFObjectMenu(
myWSFObjects)
End Module
加载 dbiWSF 数据并将其附加到 dbiWSF Schedule 的代码。
Try 'Code to load the data for the dbiWSF objects. myWSFObjects.LoadAllData() 'Code to display the dbiWSFSchedule with dbiWSF objects in the date range provided. Me.DbiWSFSchedule1.SetMainObjects(myWSFObjects, myBusinessRules, #1/2/2012#, #1/7/2012#) Catch ex As Exception
上面的几行代码会将数据加载到 dbiWSF 对象中,并将这些对象附加到 `dbiWSFSchedule` 控件。只需这些代码,就可以开箱即用地获得一个可用的仓库应用程序。数据绑定已处理完毕,上下文菜单允许设置属性,并且 日程控件负责移动和创建新的发货,同时运行业务规则和数据绑定。
B) 业务规则层
dbiWSF 的关键目标之一是集成一个健壮且通用的业务规则模型。作为快速应用程序开发人员,我们编程的核心专注于组织施加的业务规则。这些规则通常被编码在函数中,然后从多个事件中调用,然而,由于事件本身经常针对独特的返回对象和 e.arguments,为了快速交付项目,“通用”部分通常会被忽略。我们希望减轻这种影响以及对象定义更改的影响。因此,我们设计了一个函数和对象的库,它们可以响应我们对象上的 CRUD 操作,而不是特定的事件参数(例如,我们为发货更改触发业务规则,只要现有发货被修改)。这种方法允许我们编写业务规则,而不管该发货详情如何改变,无论是在 dbiWSFSchedule、dbiWSFDayView、ListView、ComboBox 还是自定义对话框中。相同的规则或规则集适用于无论是什么触发了更改。业务规则的创建和修改在产品随附的源代码和帮助文件中都有记录和模板化。甚至还有一个 UI 对话框,可以开箱即用,也可以根据不同的“控制级别”进行修改(例如,经理可以覆盖发货被添加到异常区域)。再次强调,我们有相应的视频...
C) 用户界面层和报告
DBI 作为组件供应商已有相当长的一段时间,因此我们非常熟悉控件以及与这些控件的交互。虽然我们在控件的演示和文档上花费了大量时间,但有时最好的想法来自于实际使用我们的控件。我们在 dbiWSF 中获得了这个机会,并且 Solutions Schedule for .NET Enterprise 和 Studio Controls for .NET(dbiDayView - 一个多列约会控件,dbiList - 一个基于节点的树/列表控件)的最新版本的一些想法来自于我们在 dbiWSF 中深入使用这些控件。我们进一步扩展了我们的控件,以提供 dbiWSF 对象的通用 UI 实现。将对象附加到 UI 层所需的代码很少,只需调用一个 `LoadData` 方法并传递 `dbiWSFMainObject` 对象(我知道这有点多余,但命名约定有时会带来意想不到的组合),dbiWSF 控件就会将对象应用于控件。我们包含一个 dbiWSFSchedule、dbiWSFDayView 和一个 `dbiWSFObjectMenu`(自定义上下文菜单),以及一系列对话框和支持控件。
UI 层还包含一个高度定制化的 dbiList 控件版本,该控件能够接受自定义报告对象。该控件封装了一个非常灵活的报告模板,负责“布局”职责,同时允许开发人员以编程方式向报告添加节点。这本质上是带状报告编写器和允许开发人员在 .NET 代码中生成报告节点的混合体。使用 LINQ 对现有的 dbiWSF 对象进行查询,报告的编写会容易得多。源代码中包含模板和三个预定义的报告。一如既往,这里也有一个视频...
D) 仓库概念和集成
如前所述,这不是一个简单的框架,我们做了充分的研究。发货调度世界中的一个关键概念是需要处理装卸区的例外情况。这些例外情况可能出于多种原因(装卸区维护、午休时间、人员问题、设备故障和交叉装卸)。我们实际上为此界定了两种不同的需求:一种用于一次性问题(Jimmy 开车撞坏了保险杠),另一种用于重复性例外情况(每天中午 12 点到下午 1 点不允许任何货物配送)。因此,我们为两者创建了对象。例外类允许设置例外情况的开始/结束时间以及例外适用的装卸区集合。如果要调度对 1 到 3 号装卸区进行 8:00 AM 到 10:00 AM 的动力清洗,这是理想的。重复性例外情况具有开始日期和结束日期,以及频率。这可以允许一组装卸区每天从上午 10 点到 11 点关闭,或者从 6 月 1 日到 10 月 1 日的每周二和周四关闭,用于公司烧烤(嗯,烧烤)。这些对象显示在 `dbiWSFSchedule` 和 dbiWSFDayView 的自定义区域中,但它们也嵌入在业务规则层中,因此如果开发人员使用的是纯对话框或其他界面,他们仍然可以通过业务规则类收到通知。
另一个值得注意的领域是断点装卸区。这意味着一个发货可能需要两个装卸区来进行卸货或暂存。我们允许每个发货最多使用两个断点装卸区,这意味着该发货需要位于主装卸区的左侧、右侧,或者拆分使用。
我们还投入精力研究了可用的货物类型以及装卸区与这些货物类型的布局。例如,某些装卸区位于冷藏区,有些位于干货区。dbiWSF 中的每个装卸区都可以设置一个集合,以允许特定类型的货物。附加到 OrderHeader 的每个 OrderDetail,该 OrderHeader 又附加到 Shipment,可以有一个特定的货物类型。这意味着混合装载会显示正确的货物类型。与大多数对象一样,在创建和移动发货时会应用业务规则,以确定发货上的货物类型是否与装卸区接受的货物类型匹配。与所有业务规则一样,这些可以根据级别进行调整(如果老板想将啤酒卸在主仓库,然后用手推车推入冷藏室,我们有什么理由说不)。在 dbiWSF 控件中,这些由 16x16 的图标表示。附带的图标是默认的,我们希望开发人员根据客户定义的货物类型使用自己的图标。
最后,我们暴露了大量的事件,以便集成现有系统。我们理解开发人员不想为 CRM、POS 和 ERP 系统重新发明轮子,因此我们指出了代码中可以进行这些连接的位置。每个对象都有一个基于 GUID 的键,并有几个关键的指示器字段,用于与其他系统进行关联。例如,每个 OrderHeader 对象都有一个外部键,可用于将订单 ID 或采购订单与 POS 系统关联(这允许进行入站/出站发货控制)。发货本身包含运输公司 ID 和集装箱 ID 的字段(该系统主要为卡车运输设计,但也可用于集装箱船、火车,甚至可以“移动”装卸区,用于大型运输码头,其中起重机充当装卸区)。
结论
dbiWSF 是数小时的范围界定、设计、实施、测试和文档工作的总和。这是该软件包中可用内容的一个简要摘要。有关更多信息,请访问我们的网站,并务必查看演示视频、设计理念,甚至一个功能齐全的SmartClient 演示。如果您有任何问题或意见,请随时联系info AT dbi-tech.com。
一如既往,请多保重,祝您有美好的一天!