1

Я использую Visual Studio 2008, C#, LINQ to SQL и используя datbase-редактор графического интерфейса для создания базы данных. Я хочу создать отношения от 1 до многих, но в моем случае у 1 объекта есть 2 первичных ключа. С помощью графического интерфейса edtior я создал ассоциацию, но когда программа запускается и база данных созданы, я получаю ошибку:Ассоциация Linq-To-SQL с несколькими внешними ключами Проблема

«ссылочная таблица должна иметь первичный или потенциальный ключ [FK Name = Screen_Pixel].»

XML, созданный в DBML выглядит как:

<Table Name="Screen"> 
    <Column Name="PKA1" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 
    <Column Name="PKA2" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 
    <Association Name="Screen_Pixel" Member="Pixels" ThisKey="PKA1,PKA2" OtherKey="PKB1,PKB2" Type="Pixel" /> 
</Table> 

<Table Name="Pixel> 
    <Column Name="PKB1" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 
    <Column Name="PKB2" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 
    <Column Name="PKB3" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 
    <Association Name="Screen_Pixel" Member="Screen" ThisKey="PKB1,PKB2" OtherKey="PKA1,PKA2" Type="Screen" IsForeignKey="true" /> 
</Table> 

сформированные ассоциации в C# коде:

[Association([email protected]"Screen_Pixel", [email protected]"_Screen", [email protected]"PKA1,PKA2", [email protected]"PKB1,PKB2", IsForeignKey=true)] 
[Association([email protected]"Screen_Pixel", [email protected]"_Pixels", [email protected]"PKB1,PKB2", [email protected]"PKA1,PKA2")] 

Любые идеи?

ответ

0

Почему вы используете несколько полей для первичного поля (также называемого «составным основным полем»)?

Некоторые школы и книги учат использовать «Композитные первичные ключи», но на самом деле это не очень хорошая идея. Многие программы не позволяют эти поля, и даже если это так, с ними трудно справиться.

Всегда лучше использовать первичный ключ одного поля.

Мое предложение состоит в том, чтобы сохранить эти поля в качестве стандартных полей или внешних ключей, добавить новое поле, которое автоматически присваивается или увеличивается.

Пример:

<Table Name="Screen"> <Column Name="ScreenKey" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="ScreenField1" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="ScreenField2" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Association Name="Screen_Pixel" Member="Pixels" ThisKey="ScreenKey" OtherKey="ScreenKey" Type="Pixel" /> 

</Table> 

<Table Name="Pixel> 

<Column Name="PixelKey" Type="System.Int64" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="ScreenKey" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="PixelField1" Type="System.Int64" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="PixelField2" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Column Name="PixelField3" Type="System.Int32" IsPrimaryKey="false" CanBeNull="false" UpdateCheck="Never" /> 

<Association Name="Screen_Pixel" Member="Screen" ThisKey="ScreenKey" OtherKey="ScreenKey" Type="Screen" IsForeignKey="true" /> 

</Table> 
+0

Я не был оригинальным автором базы данных, и именно так была написана база данных. Я надеялся не делать этого, потому что проще и интуитивно, чтобы несколько внешних ключей определяли объекты. Если я не услышу больше ответов в понедельник, я дам ему шанс. – John

+4

Неплохая идея использовать составные первичные ключи, когда оба значения неизменяемы и определяют уникальность строки, а в противном случае - просто плохой совет. Если решение ORM не может обрабатывать составные первичные ключи, это недостаток решения ORM. Мы не должны моделировать наши данные, чтобы соответствовать ограничениям ORM. –

1

Так как я боролся с чем-то подобным, и этот вопрос был близок к моему, я добавлю свои 2 цента здесь для следующей души, которые могли бы прийти с той же проблемой (создание базы данных во время выполнения из объектной модели).

Если составной ключ не действительно должен быть первичный ключ (то есть вы просто хотите, чтобы обеспечить уникальность комбинации) решение заключается в следующем:

  • добавить регулярный первичный ключ (тождественность дб целое сгенерированный столбец), который вы будете ссылаться на внешний ключ.
  • обеспечивает ограничение уникальности с дополнительным шагом на вашем DataContext и т.д .:

    yourDataContext.ExecuteCommand("ALTER TABLE Stuff ADD UNIQUE (unique_thing_1, unique_thing_2, unique_thihng_3)"); 
    

затем подают сгенерирует исключение при попытке вставки повторяющихся полей.