1

我有类似这样的设计(虽然有小小的,纤细有点复杂):许多一对多具有唯一约束和有条件更新

MySQL layout design

这是一个多对多多种关系。扫描可以拥有许多定位的页面,但定位的页面可能属于许多扫描。

我遇到的麻烦是我不知道如何在URL上添加一个唯一的约束,这样当扫描页面被保存并且具有这样的URL的条目已经存在时,它不应该创建一个新的一。相反,新的scan_locatedpage条目应链接到已存在的定位页面,并且(如果不同)更新其校验和。

只,我不知道该怎么做。

目前我的代码看起来是这样的:

public LocatedPageMap() 
{ 
    Id(x => x.Id); 
    Map(x => x.Url) 
     .Not.Nullable(); 
    Map(x => x.Checksum); 
    HasManyToMany(x => x.ScansFoundWith) 
     .Cascade.All() 
     .Inverse() 
     .Table("Scan_LocatedPage"); 
} 

public ScanMap() 
{ 
    Id(x => x.Id); 
    Map(x => x.Date) 
     .Not.Nullable(); 
    HasManyToMany(x => x.Located_Pages) 
     .Cascade.SaveUpdate() 
     .Table("Scan_LocatedPage"); 
} 

当然,这是行不通的。每次保存新的扫描时,都会添加一个新的位于页面的页面,尽管存在Url。

我不知道如何实现这种效果,我不确定在哪里/如何看。我已经阅读了一系列标题为“独特”的多对多问题,但没有发现任何有用的东西。当然'因为我不确定要查找什么。

编辑

或者,也许我应该简单地将情况处理程序为我的应用程序逻辑,而不是指望流利的照顾,对我?

回答

2

这类问题属于上层比映射。您可以/应该做的是使用提供的网址搜索现有对象LocatedPage。如果找到 - 使用它,如果没有 - 创建新的。 我们正在进行数据绑定期间在上层(服务,业务)上做这些事情。

有几点我想你是知道的:

1)Chapter 24. Best Practices说:

一个真正的许多-to-many关联良好usecases是罕见的。当你需要额外的信息存储在“链接表”中时,大部分是 。 在这种情况下,使用两个一对多关联到 中间链接类更好。事实上,我们认为大多数协会 是一对多和多对一的,您在使用任何其他关联风格时应该小心,并问问自己是否真的需要。

请考虑一下。我们根本不使用多对多。具有中间对象作为一个完整的实体可以带来很多好处(例如搜索基于子查询)

2)级联

许多一对多使用级联时要小心。这不是中间/配对表的设置。它是为第二端实体设置的。所以一旦你的LocatedPageMap被删除,所有ScansFoundWith项目(Scan)也将被删除。通常...级联不是你想要设置多对多的。配对表是“级联总是”

+0

这是评论的第三版本,我发现它确实不直观,“Enter”键用于提交。 :]回到话题:你是对的,一对多和多对一的关系可能会是一个更好的解决方案。你能否告诉我一个简单的例子,看看这样的转换是怎么样的?我不确定我是否正确。 :)此外,我只是有点不确定我应该在链接实体中存储什么样的数据。这些应该是“联系特定的”,还是那些能够访问而不查询其他实体的表的访问者呢? :) – moskalak

+1

请尝试阅读此:http://stackoverflow.com/q/15510748/1679310,在这里我试图解释这一点。或者这里的类似http://stackoverflow.com/q/19687006/1679310。最大的优点是简化了处理。你可以在子查询中看到示例(http://stackoverflow.com/q/18363386/1679310)。因此,您可以稍后通过查询配对对象来找到一些“Scan”或“LocatedPage”... –