Отображение внешнего ключа с пользовательским именем столбца
Я использую Entity Framework 4.3 в коде с Oracle. Я получаю следующую ошибку:
System.InvalidOperationException: параметр ForeignKeyAttribute в свойстве "WidgetSequence" для типа "WidgetDistributor.WidgetEntity" недопустим. Имя внешнего ключа "WIDGETSEQUENCE_ID" не было найдено в зависимом типе "WidgetDistributor.WidgetEntity". Значение Name должно быть разделенным запятыми именами свойств внешнего ключа.
Мои объекты такие:
[Table("WIDGETENTITIES")]
public class WidgetEntity {
[Column("WIDGETENTITY_ID")]
public int Id { get; set; }
[ForeignKey("WIDGETSEQUENCE_ID")]
public WidgetSequence Sequence { get; set; }
// and other properties that map correctly
}
[Table("WIDGETSEQUENCES")]
public class WidgetSequence {
[Column("WIDGETSEQUENCE_ID")]
public int Id { get; set; }
[Column("NUMBER")]
public int Number { get; set; }
}
Мой код кажется правильным. Что я сделал не так, здесь?
Ответы
Ответ 1
ForeignKey
attibute ожидает имя свойства в вашем классе в качестве аргумента, но вы указали имя столбца. Используйте плавные сопоставления.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<WidgetEntity>()
.HasRequired(w => w.Sequence)
.WithMany()
.Map(m => m.MapKey("WIDGETSEQUENCE_ID"));
}
Ответ 2
Если вы не хотите использовать свободный синтаксис, есть три других способа реализации ссылки с использованием аннотаций данных (лично я предпочитаю аннотации данных, поскольку они кажутся более легкими для чтения и написаны чуть выше свойства, которое они затрагивают):
1.1)
Использовать ForeignKey (с ассоциированным свойством) - версия 1
[Table("WIDGETENTITIES")]
public class WidgetEntity {
[Column("WIDGETENTITY_ID")]
public int Id { get; set; }
[Column("WIDGETSEQUENCE_ID")]
public int WidgetSequenceId { get; set; }
[ForeignKey("WidgetSequenceId")] //Has to be a property name, not table column name
public WidgetSequence Sequence { get; set; }
// and other properties that map correctly
}
[Table("WIDGETSEQUENCES")]
public class WidgetSequence {
[Column("WIDGETSEQUENCE_ID")]
public int Id { get; set; }
[Column("NUMBER")]
public int Number { get; set; }
}
1.2)
Использовать ForeignKey (с ассоциированным свойством) - версия 2
[Table("WIDGETENTITIES")]
public class WidgetEntity {
[Column("WIDGETENTITY_ID")]
public int Id { get; set; }
[ForeignKey("Sequence")] //Has to be a property name, not table column name
[Column("WIDGETSEQUENCE_ID")]
public int WidgetSequenceId { get; set; }
public WidgetSequence Sequence { get; set; }
// and other properties that map correctly
}
[Table("WIDGETSEQUENCES")]
public class WidgetSequence {
[Column("WIDGETSEQUENCE_ID")]
public int Id { get; set; }
[Column("NUMBER")]
public int Number { get; set; }
}
2)
Вы также можете использовать атрибут InversePropertyAttribute.
[Table("WIDGETENTITIES")]
public class WidgetEntity {
[Column("WIDGETENTITY_ID")]
public int Id { get; set; }
[InverseProperty("WidgetEntities")]
public WidgetSequence Sequence { get; set; }
// and other properties that map correctly
}
[Table("WIDGETSEQUENCES")]
public class WidgetSequence {
[Column("WIDGETSEQUENCE_ID")]
public int Id { get; set; }
[Column("NUMBER")]
public int Number { get; set; }
public virtual List<WidgetEntity> WidgetEntities { get; set; }
}
Ответ 3
Существует таблица под названием "Пользователи", и у нее есть первичный ключ с именем UserID.
Существует другая таблица, называемая Directory, и в ней есть столбец с именем UserID, который определяется как внешний ключ для таблицы Users.
Я могу использовать аннотацию ForeignKey для сопоставления внешнего ключа следующим образом:
[ForeignKey("xyzzy")]
public int? UserID { get; set; } // This is a column in the table
public virtual User xyzzy { get; set; } // This is my instance of User