Подтвердить что ты не робот

Отображение внешнего ключа с пользовательским именем столбца

Я использую 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; }
}

Мой код кажется правильным. Что я сделал не так, здесь?

4b9b3361

Ответ 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