我有一个关于在ASP.NET MVC中保存对象列表的问题。 首先我没有使用EntityFramework或Nh像ORM工具,只需使用Ado.net
假设我有一个对象产品,我想通过javascript收集所有产品数据,并在一次通话中批量更新产品列表。
我的问题是我何时应该区分插入,更新或删除的项目?
一个策略是我在DTO对象上有一个枚举属性 也在javascript ViewModel上,当我添加一个项目时 viewModel,我标记了要添加的对象,如果我更改了一个Item,我 标记为更新。所以当这个请求来到行动时,我可以 知道要插入或更新的项目。
区分数据与服务器端,只需给我一个对象列表,在服务器端,首先从数据库中检索当前数据,比较数据,然后检查要插入或更新的记录。
从客户端传递的数据,只需删除当前数据并插入新数据
我希望有人可以给我一个建议,处理这种情况的最佳做法是什么,我认为这很常见,但我找不到最佳解决方案。
答案 0 :(得分:1)
第三种策略适用于简单的情况,例如当您想要更新采购订单项时,订单将不会有太多的OrderLineItems。但是,您必须注意并发问题。
我认为你的第一个策略最适合一般情况。它也很容易实现。如果要将服务发布到第三方,通常客户端必须遵循服务定义和要求。
<强>更新强>
对于第一种策略:如果您不希望客户端必须为其数据指定状态,请为它们执行此操作。您可以将SaveOrder服务分成较小的服务:CreateOrder,UpdateOrder,DeleteOrder。
答案 1 :(得分:1)
我见过选项1,其中添加/删除/修改的项目在javascript数组中维护并发回服务器。但由于某种原因,我不喜欢它可能是因为编写客户端代码来维持状态。
所以,我使用了第二个选项并感谢LINQ使我的任务更容易。假设列表有一些唯一的id,下面是伪代码。注意:新添加的项目应具有唯一的随机ID,否则可能会将它们视为已存在的项目。在我的情况下它的GUID,所以没有超越的可能性。
var submittedIds = vmList.Select(a=>a.Id).ToList();
var dbIds = dbList.Select(d=>d.Id).ToList();
//Added items
var newIds = submittedIds.Except(dbIds).ToList();
//loop over newIds and construct list object to contain newly added items
//Deleted items
var deletedIds = dbIds.Except(submittedIds).ToList();
//Modified items
var modifiedIds = dbIds.Intersect(submittedIds).ToList();//if the values don't change, update statement won't do any harm here
除非您处理大量列表,否则此方法会提供合理的性能。
我认为第三种选择并不好。例如:如果您计划在表上实现审计功能,则会给您错误的功能。如果插入了新记录,则所有记录的条目都将被删除,然后插入一个错误,因为只插入了一个。