У меня есть база данных с большим количеством отношений. К сожалению, это старая поддерживаемая база данных, которая, похоже, не понимает концепцию ассоциации или ключей, которой иногда не хватает. Это основное использование в другом приложении, поэтому я больше не хочу менять базу данных (но скорее настраиваю Entity Framework)Использовать внешние ключи в качестве первичного ключа
Проблема, которую я имею, заключается в попытке использовать внешние ключи в качестве первичных ключей, как (я думаю) используй это.
Мои таблицы называются
Operation{ Criteria { Parameter{ CriteriaSelection {
ID ID, ID, ID,
.. .. .. ..
} } } }
CheckpointOperation {
ID,
Criteria_ID,
..
}
CheckpointParameter {
// missing primary key
CheckpointOperation_ID, // a CheckpointOperation has many CheckpointParameters
CriteriaSelection_ID, // a CheckpointParameter has one CriteriaSelection
Parameter_ID, // .. and one Parameter
..
}
Проблема здесь в том, что CheckpointParameter
не имеет первичный ключ, определенный конкретно, а первичный ключ { CheckpointOperation_ID, CriteriaSelection_ID, Parameter_ID }
. Теперь я пытаюсь сопоставить это в EntityFramework с class CheckpointParameterMap : EntityTypeConfiguration<CheckpointParameter>
.
public class CheckpointOperation
{
public int Id { get; set; }
public virtual Operation Operation { get; set; }
public virtual ICollection<CheckpointParameter> Parameters { get; set; }
}
public class CheckpointParameter
{
public int OperationId { get; set; }
public virtual CheckpointOperation CheckpointOperation { get; set; }
public virtual CriteriaSelection Criteria { get; set; }
public virtual QualityParameter Parameter { get; set; }
}
public class CheckpointParameterMap : EntityTypeConfiguration<CheckpointParameter>
{
public CheckpointParameterMap()
{
HasKey(p => new { p.OperationId });
Property(p => p.OperationId)
.HasColumnName("CheckpointOperation_ID");
HasRequired(p => p.CriteriaSelection)
.WithRequiredDependent()
.Map(map => map.MapKey("CriteriaSelection_ID"));
HasRequired(p => p.Parameter)
.WithRequiredDependent()
.Map(map => map.MapKey("Parameter_ID"));
HasRequired(p => p.CheckpointOperation)
.WithMany(o => o.CheckpointParameters)
.HasForeignKey(p => p.OperationId);
}
}
Но это дает мне ошибку, как из
Multiplicity is not valid in Role 'CheckpointParameter_CheckpointOperation_Source' in relationship 'CheckpointParameter_CheckpointOperation'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be '1'.\r\n"}
Так что я попытался удалить HasKey
, но это дает мне ошибку
EntityType 'CheckpointParameter' has no key defined. Define the key for this EntityType.\r\n\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'CheckpointParameters' is based on type 'CheckpointParameter' that has no keys defined.\r\n"}
Затем я попытался использовать иностранные критерии, а также первичный ключ, так как у меня есть название столбца:
public class CheckpointParameter
{
...
public int CriteriaSelectionId { get; set; }
...
}
public CheckpointParameterMap()
{
HasKey(p => new { p.OperationId, p.CriteriaSelectionId });
//...
Property(checkpointParameter => checkpointParameter.CriteriaSelectionId)
.HasColumnName("CEC_ID");
}
Но это дает мне следующую ошибку:
{"Schema specified is not valid. Errors: \r\n(48,6) : error 0019: Each property name in a type must be unique. Property name 'CriteriaSelection_ID' was already defined."}
Что такое правильный способ определения первичного ключа, которые являются внешними ключами, без изменения базы данных?
Вы побегать отдельный запрос по этим столбцам в копии производственных данных? Похоже, вы уверены, что сочетание этих ключей образует естественный ключ таблицы. Если это так, то вперед и создайте первичный ключ SQL для этих столбцов. –
У меня есть копия производственных данных, да. У меня есть доступ к базе данных Oracle, где определены таблицы, которые содержат следующее (что для меня подтверждает, что это ключ): 'CREATE UNIQUE INDEX" X "." I $ CEPOQ $ UNIQUE "ON" X "." CEPOQ "(" CEC_ID "," CEPO_ID "," Q_ID "," FRQ ")', где cec - это критерии, cepo - Ch.Operation, а q - параметр. Пожалуйста, поправьте меня, если я ошибаюсь – Default
В этом ответе http://stackoverflow.com/a/15704189/2516770 указано, что Oracle не считает уникальный индекс также уникальным ограничением или ключевым ограничением. Исходя из первого сообщения об ошибке, я предполагаю, что создание уникального ограничения ключа скажет поставщику Oracle EF, что он имеет дело с отдельным значением для 1 стороны отношения (1: n). Однако это всего лишь предположение. –