0

我的数据库中有两个表:

Wiki
    WikiId
    ...

WikiUser
    WikiUserId (PK)
    WikiId
    UserId
    IsOwner
    ...

这些表具有一对多(WikiUser)的关系。

我将如何在我的 LINQ 实体类中实现以下业务规则:

“一个 Wiki 必须只有一个所有者?”

我尝试如下更新表格:

Wiki
    WikiId (PK)
    OwnerId (FK to WikiUser)
    ...

WikiUser
    WikiUserId (PK)
    WikiId
    UserId
    ...

这会强制执行约束,但如果我从 Wiki 的 WikiUser 集合中删除所有者的 WikiUser 记录,我会收到一个丑陋的 SqlException。这似乎很难在 UI 中捕获和处理。

有没有办法在生成 SqlException 之前执行此检查?构建数据库的更好方法?一种捕获 SqlException 并将其转换为更有用的方法的方法?

编辑:如果可能,我希望将验证规则保留在 LINQ 实体类中。

编辑2:关于我的具体情况的更多细节。

在我的应用程序中,用户应该能够从 Wiki 中删除用户。他们应该能够删除任何用户,除了当前被标记为 Wiki 的“所有者”的用户(一个 Wiki 必须始终只有一个所有者)。

在我的控制逻辑中,我想使用这样的东西:

wiki.WikiUsers.Remove(wikiUser);
mRepository.Save();

并将任何违反的规则转移到 UI 层。

我不想做的是:

if(wikiUser.WikiUserId != wiki.OwnerId) {
    wiki.WikiUsers.Remove(wikiUser);
    mRepository.Save();
}
else {
    //Handle errors.
}

我也不是特别想将代码移动到我的存储库(因为没有任何指示不使用本机 Remove 函数),所以我也不想要这样的代码:

mRepository.RemoveWikiUser(wiki, wikiUser)
mRepository.Save();

这是可以接受的:

try {
    wiki.WikiUsers.Remove(wikiUser);
    mRepository.Save();
}
catch(ValidationException ve) {
    //Display ve.Message
}

但这会捕获太多错误:

try {
    wiki.WikiUsers.Remove(wikiUser);
    mRepository.Save();
}
catch(SqlException se) {
    //Display se.Message
}

我也不想明确调用业务规则检查(尽管它可能变得必要):

wiki.WIkiUsers.Remove(wikiUser);
if(wiki.CheckRules()) {
    mRepository.Save();
}
else {
   //Display broken rules
}
4

1 回答 1

0

这个问题有太多的依赖关系,无法很好地回答——其中最大的一个是您计划在哪里全面执行业务规则。按照优先顺序,您必须问:您有业务规则层吗?如果没有,您是否有独立的数据访问层?如果不是,您是否使用数据提供者模型?如果没有,那么您正在考虑在处理配置 UI 的任何地方执行这种事情(或处理 SqlException)。

对于像 wiki 这样的东西,您可能不需要非常复杂的业务规则引擎,因为您的问题域已经受到了很好的限制。此外,这听起来像是一种几乎永远不会改变的规则,因此将其隔离在正式的规则层中有点矫枉过正。因此,您最好将这种约束放在数据层或数据提供者中。

例如,如果您使用 Linq to Sql,您可以通过将模型中的 OwnerId 属性设置为与 WikiUser 表的关系绑定的不可空属性来反映您在 SQL Server 中所做的事情。这将强制填充 OwnerId 属性(因为它不可为空)并为您提供您正在寻找的唯一约束。

于 2009-08-08T01:15:47.007 回答