允许使用 LINQ to SQL 在分页 WPF MVVM 应用程序中选择性保存实体
我正在开发一个允许编辑 SQL Server 数据库的应用程序。我遇到的问题是允许用户保存一些更改但丢弃其他一些更改。我希望得到一些关于我的设计的建议。
该应用程序是MVVM。作为模型,我使用 LINQ to SQL 类。一般来说,每个实体类都有 ViewModel 类。然后,我为每个实体实例创建一个 ViewModel 实例。
该界面由一个窗口组成,我在其中切换视图以实现分页系统。大多数情况下,实体、视图模型、视图和页面之间存在 1:1 的关系。
以下示例可以最好地描述我遇到的问题:
请考虑下表:
- 服务
- StaffMembers
- StaffMemberAssignments
我有一个实体 Service。它在数据库中由“服务”表中的一行表示,并具有“名称”、“合同值”和“类型”等参数。
每个服务还包含一个 StaffMemberAssignments 列表。 StaffMemberAssignments 存储在它们自己的表中,并包含一些有关分配的参数以及两个外键 - 一个指向已分配它们的服务,另一个指向 StaffMember 表,指向正在分配的 StaffMember。
总结一下:
服务 - StaffMemberAssignment - StaffMember
编辑服务后(在 ServiceView 上,使用基于单个服务实例的 ServiceViewModel),用户可以“保存更改”或“取消”。 “保存更改”命令将对 LINQ to SQL 数据上下文的所有更改提交到数据库。取消将服务对象恢复到其原始状态。
用户可以将 StaffMember 添加到服务 - 这将创建 StaffMemberAssignments 将 StaffMember 链接到服务。
棘手的部分来了
如果用户想要将 StaffMember 添加到服务中,则将打开 StaffMembersListView(它是一个带有选择选项的表)。此视图将替换 ServiceView 作为当前页面。选择 StaffMember 后,分页返回到 ServiceView,一切正常,创建新的 StaffMemberAssignment 将 StaffMember 链接到服务。
但是,在查看员工列表时,用户可以选择“创建新员工”。这将打开带有新 StaffMember 实例和视图模型的 StaffMemberView。用户可以在此处输入新员工的详细信息,然后可以“保存更改”或“取消”。 “取消”只是返回到上一页并丢弃新创建的 StaffMember 实体,而“保存”则将新实体提交到数据库。然后返回 StaffMembersListView,用户可以从列表中选择新的 StaffMember,并返回到已进行新 StaffMemberAssignment 的 ServiceView。
问题是
创建新的 Staffmember 后,保存它会将所有数据上下文更改推送到数据库。这意味着用户对服务的任何编辑都已被推送到数据库。如果用户在创建新的 StaffMember 后选择“取消”服务,则服务将不会返回到原始状态。
期望的行为是,当创建 StaffMember 并“保存”-d 时,仅将新的 StaffMember 推送到数据库。用户可以从列表中选择它,并将其添加到服务中。然后,如果用户取消服务更改,服务将返回到其原始状态,但新创建的 StaffMember 将保留在 StaffMember 表中。毕竟,它已经被拯救了。
谷歌搜索选择性保存实体的方法给我的印象是不应该这样做。那么如何修改我的数据层设计或 UI 设计以获得我想要的功能呢?还是我想要的不现实?
导致问题的步骤的最终总结:
- 用户打开服务实体进行编辑
- 用户希望选择 StaffMember 链接到服务
- 用户创建新的 StaffMember
- 新的 StaffMember 被保存到数据库中。
对服务的更改也会保存,但不应保存。 - 用户选择要添加到的 StaffMember 服务(新的或任何 其他)
- 用户取消对服务的更改。 服务必须恢复到原来的状态 陈述但由于抵押品的原因不能 保存在步骤4中。
I am developing an application that allows the editing of a SQL Server database. The problem that I am having is with allowing the user to save some changes but discard some others. I am hoping for some advice regarding my design.
The application is MVVM. As Model I use the LINQ to SQL classes. In general, I have ViewModel classes for each entity class. I then create a ViewModel instance for each entity instance
The interface consists of a single window, where I switch Views to implement a paging system. For the most part, there is a 1:1 relationship between Entities, ViewModels, Views and Pages.
The problem I am having is best described by the following example:
Consider the following tables:
- Services
- StaffMembers
- StaffMemberAssignments
I have an entity, Service. It is represented in the database by a row in the Services table, and has parameters such as "Name", "ContractValue" and "Type".
Each Service also contains a list of StaffMemberAssignments. StaffMemberAssignments are stored in their own table and contain some parameters regarding the assignments, as well as two foreign keys - one to the Service where they have been assigned, and one to the StaffMember table, to the StaffMember that is being assigned.
In summary:
Service - StaffMemberAssignment - StaffMember
After editing a Service (on the ServiceView, using a ServiceViewModel based on a single Service instance), the user can "Save Changes" or "Cancel". The "Save Changes" command submits all changes to the LINQ to SQL datacontext to the Database. Cancel restores the Service object to its original state.
The user can add StaffMembers to the Service - this creates StaffMemberAssignments to link the StaffMember to the Service.
Here comes the tricky part
If the user wants to add a StaffMember to the Service, the StaffMembersListView is opened up (it's a table with the option of selection). This view replaces the ServiceView as the current page. After selecting a StaffMember, paging return to the ServiceView and all is well, with the new StaffMemberAssignment created to link the StaffMember to the Service.
However, while viewing the StaffMembers list, the user can choose to "Create new Staffmember". This opens the StaffMemberView with a new StaffMember instance and viewmodel. Here the user can enter details for the new StaffMember and can then "Save Changes" or "Cancel". "Cancel" simply returns to the previous page and discards the newly created StaffMember entity, while "Save" commits the new entity to the database. The StaffMembersListView is then returned, the user can select the new StaffMember from the list, and return to the ServiceView where the new StaffMemberAssignment has been made.
The problem is
When the new Staffmember was created, saving it pushed all datacontext changes to the DB. This means that any edits to the Service that the user was busy with, have also been pushed to the DB. If the user chooses to "Cancel" the service after creating the new StaffMember, the Service will not be returned to its original state.
The desired behaviour is that when the StaffMember is created and "Save"-d, only the new StaffMember is pushed to the DB. The user can select it from the list, adding it to the Service. Then, if the user Cancels the Service changes, the Service returns to its original state, but the newly created StaffMember will remain in the StaffMember table. It has, after all, been Saved.
Googling for ways to selectively save entities gave me the impression that this is not supposed to be done. So how can I modify either my data layer design or my UI design to get the functionality that I want? Or is what I want unrealistic?
Final Summation of steps leading to problem:
- User opens Service entity for editing
- User wishes to select StaffMember to link to Service
- User creates new StaffMember
- New StaffMember is saved to DB.
Changes to Service are also saved, but should not be saved. - User selects a StaffMember to add to
the Service (the new one or any
other) - User Cancels changes to Service.
Service must return to original
state but cannot, due to collateral
save in step 4.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用不同的模型上下文实例来创建 StaffMember 不是一个选项吗?
Wouldn't it be an option to use a different model context instance for creating the StaffMember?