【发布时间】:2011-09-13 03:35:53
【问题描述】:
由于我正在开发的网站的设计方式的性质,我现在必须解决一个问题。
我将尝试将此问题编写为与语言无关,但该站点是在 ASP.Net 中使用 C# 完成的。
概述
对于任何给定的“对象”,我们网站的结构如下所示:
- ASPX 页面
- 多个用户控件(ascx 页面)
- 文本框、组合框、标签、 按钮等
- 多个用户控件(ascx 页面)
这意味着,如果我们有一个用户页面并且该页面可能有 3 个用户控件。一个用于用户信息(姓名、电子邮件等),一个用于地址(城市、州、邮编等),一个用于区域设置(时区、语言等)
3 个用户控件上的所有这些字段都存储在数据库的同一个表中。
现在,我们使用 DataBinding 和 EntityFrameworks 来填充数据,这意味着当我们保存一个对象时,我们实际上调用了 3 次 save(每个 UserControl 1 次)。
(与语言无关:我们实际上并没有 分配像
User.Name = "Bob"这样的值,它由框架处理)
因为 UserControl 只知道它包含的字段,所以当数据绑定保存它“认为”其他字段现在是空白的。 (即地址控制保存,现在“电子邮件”和“名称”为空值)。为了“解决”这个问题,有一个名为“MapOldToNew”的方法,它会抓取旧记录并填充即将保存的新对象上的值。这是通用的,这意味着我们在 Address Usercontrol 上没有一个方法说“去获取 Name 和 Email 字段并填写它们”,而是循环遍历 Entity(object) 的所有属性以及如果一个值在新对象上是NULL,但在旧对象上是NOT NULL(当前在数据库中即将被覆盖的对象),它将使新值等于旧值。
问题
日期。我们允许在我们的数据库中使用 NULL 日期。
如果用户填写“生日”并保存,他们现在在数据库中的字段中有一个生日值。
如果他们返回并清除网页上的“生日”字段并保存,MapOldToNew 方法会抓取旧记录,看到“生日”不为空,并且在要保存的新对象上为空,它将覆盖新值 (NULL) 与旧值(例如 '7/23/1981')。
解决方案?
- 返工我们的系统以不使用
UserControls 而是拥有所有
控制同一页,从而
减少我们需要的次数
保存而不需要
MapOldToNew。现在,让我们 假设这是不可能的 解决方案(即使它是一个 我觉得应该为 很多原因)。 - 全部存储 日期作为字符串并进行转换 在加载和保存。 (字符串不 有同样的问题,因为一旦 字符串已修改,现在是 一个空字符串,而不是 NULL)
- 不允许在
数据库并始终存储
DateTime.MinValue并且不要 加载时显示。
这些是我脑海中浮现的想法。为了争论起见,让我们假设#1是不可能的(因为我觉得管理层不会喜欢完成所需的时间)。
你会如何“解决”这个问题?
另一种解释
这里有更多的问题。
用户记录有 2 个字段。姓名和生日。
假设有 1 个带有 2 个用户控件 (ascx) 的 ASPX 页面。
UserControl1 有一个 DatePicker 数据绑定到“BirthDate”。
UserControl2 有一个文本框数据绑定到“名称”。
当 UserControl1 在 ObjectContext 上调用 Update 时,它发送的 User 对象如下所示:
{ Name = NULL, BirthDate = 8/13/1980 }
MapOldToNew 查看数据库记录,发现名称应该是“Bob”,因此它会填充值并保存记录。
UserControl2 现在调用 Update,User 对象如下所示:
{ Name = "John", BirthDate = NULL }
MapOldToNew 发现 BirthDate 为 NULL,因此它使用数据库中的 8/13/1980 覆盖它,并且记录保存并且数据库具有正确的值。
现在假设用户返回并删除 BirthDate 值。当 UserControl2 调用 MapOldToNew 时,它发现 BirthDate 为 NULL(用户想要的)并从数据库中覆盖它。
如果它没有从数据库中覆盖它,它将始终将其保存为 NULL,并且用户将永远无法设置 BirthDate。
【问题讨论】:
-
当然问题与语言无关。否则,如果您在 VB.NET 中编程,您可能不会遇到完全相同的问题。
-
是的,但它也与 ASP.Net 无关。从 MVC 模式的角度来看它。一个视图有多个子视图,它们都使用部分填充的模型调用同一个 Controller.Save,因此它们都调用 MapOldToNew,它用数据库中的值覆盖 NULL 日期。
-
你的问题是
MapOldToNew-function。我不熟悉 Entity-Framework,但必须可以从数据库中加载旧值,覆盖 UC 中的列并保存它。如果可以(不是吗?)部分更新记录(仅更改的列),那就更好了。 -
谷歌搜索几分钟后,我找到了Stub Entities。看看这个视频:screencast.com/t/ZGQyY2I5ZWE
-
@Tim - 这可能值得一看,但需要在 100 多个用户控件上手动填充大约 50 多个实体
标签: asp.net language-agnostic architecture