如何处理相互/递归的相关表?

时间:2010-06-25 23:39:18

标签: c# .net sql linq

我对数据库和SQL很新。我有一个问题,我有两个表都包含另一个主键的外键。我的问题是我有大量的元素,可以有不同语言的多个名称,但必须有一个主要的名称/语言。 alt text http://img688.imageshack.us/img688/1121/11768540.png

首先,我想知道这是否可行,还是我应该放弃?显而易见的解决方案是在ElementName表中有一个额外的布尔字段来表示IsDefaultName,但它为查询和更新增加了一些额外的复杂性。如果这是最佳解决方案,如果设置了IsDefaultName并且表中已经有一个具有相同ElementIdIsDefaultName集的条目,那么如何将ElementName表限制为不接受任何提交(或者我需要手动查询?

我正在尝试在这里使用LINQ to SQL。我用来尝试插入新项目的代码在SubmitChanges上引发了一个异常The INSERT statement conflicted with the FOREIGN KEY constraint "FK_ElementName_Element".我可以理解为什么会这样,但是想知道是否有修复/更好的解决方案。

var db = new MyDBDataContext();
var element = new Element();
var elementName = new ElementName() {
    ElementName1 = "MyElement",
    Language = "English",
};
element.ElementName = elementName;

db.Elements.InsertOnSubmit(element);
db.ElementNames.InsertOnSubmit(elementName);
db.SubmitChanges();

2 个答案:

答案 0 :(得分:2)

为什么不简单地使用像这样的自联接:

Create Table Elements( 
                        ElementId... Not Null Primary Key
                        , DefaultElementId ... Not Null 
                             References Elements( ElementId )
                        , Name ...
                        , Language ...
                        )

默认名称是ElementId = DefaultElementId。

顺便说一句,这是一个guid PK比标识列更好的地方。使用guid PK,您可以从客户端生成ElementId和DefaultElementId。如果您正在使用具有此架构的标识列,则可能必须创建一个具有已知值(如零)的“未知”elementId,以便您可以执行插入操作,然后转向并在单个事务中执行所有更新。

**附加**

鉴于您在评论中所说的话,听起来您正在尝试本地化元素数据。我倾向于建议在Elements表中添加一个不可为空的“Name”列,表示语言中性或默认语言名称。您的ElementNames表将具有Elements表的外键,并且只在本地化元素名称时填充该表。如果请求的语言没有本地化名称,那么您的查询将需要在请求的语言名称和元素表中的名称上合并。

答案 1 :(得分:2)

解决方案1 ​​

element
------------------
element_id
~....

element_name
------------------
element_name_id
fk_element_id
name
language_id
is_default_name  Default ( 0 )

Trigger:
if ( ( select count ( 1 ) from element_name where is_default_name = 1 ) > 1 )
BEGIN
    raisError ( 'only 1 element_name may be marked is_default_name = true.', 16, 1 );
END

解决方案2

element
------------------
element_id ( pk )
~....

element_name
------------------
element_name_id ( pk )
fk_element_id
name
language_id

element_name_default
------------------
fk_element_id
fk_element_name_id
( pk - fk_element_id, fk_element_name_id )

解决方案3

element
------------------
element_id
fk_element_name_id_default NULL
~....

element_name
------------------
element_name_id
fk_element_id
name
language_id

order of code:
* Insert to element_name
* update of element

我会坚持你所拥有的,因为它很好,只是:

db.Elements.InsertOnSubmit(element);
db.ElementNames.InsertOnSubmit(elementName);
//I don't know this syntax to say
//  set the property of element.fk_element_name_id_default 
//  to the newly inserted elementName from above
db.Elements.?.?
相关问题