1

Я ударил проблему при попытке удалить записи из-за ограничений FK. Поэтому я вернулся к чертежной доске и стараюсь указать, как должны работать отношения.Entity framework от одного до нуля или одного отношения без свойства навигации

Вот мой код первые классы:

public class MemberDataSet 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public int? DeferredDataId { get; set; } 
    [ForeignKey("DeferredDataId")] 
    public virtual DeferredData DeferredData { get; set; } 
} 

public class DeferredData 
{ 

    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    //other properties 
} 

То, что я ищу, чтобы добиться того, что MemberDataSet имеет ноль или один DeferredData. Я могу получить доступ к DeferredData из MemberDataSet, но DeferredData не нуждается в свойствах навигации для MemberDataSet. DeferredData должен строго требовать MemberDataSet. В идеальном мире удаление MemberDataSet будет поэтому удалять DeferredData, если они назначены.

То, что казалось мне то, что я хотел бы указать это:

modelBuilder.Entity<MemberDataSet>().HasOptional(d => d.DeferredData).WithRequired().WillCascadeOnDelete(true); 

т.е. MemberDataSet имеет возможность DeferredData но DeferredData имеет необходимый MemberDataSet и эти отношения должны каскадом на удаление.

Однако, я тогда получаю сообщение об ошибке:

ForeignKeyAttribute на имущество «DeferredData» по типу «MemberDataSet» не является допустимым. Имя внешнего ключа «DeferredDataId» не было найдено на зависимом типе «DeferredData». Значение Name должно быть разделенным запятыми именами свойств внешнего ключа.

Редактировать

Почувствовав доволен ответом Сэма ниже я пошел вперед и изменил атрибуты несколько других ForeignKey. MemberDataSet имеет другое свойство SignedOffBy, которое является пользовательским профилем. Это раньше выглядел следующим образом:

public class MemberDataSet 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public int? DeferredDataId { get; set; } 
    [ForeignKey("DeferredDataId")] 
    public virtual DeferredData DeferredData { get; set; } 

    public int? SignedOffById { get; set; } 
    [ForeignKey("SignedOffId")] 
    public virtual UserProfile SignedOffBy { get; set; } 
} 

После обсуждения ниже на то, что ForeignKey атрибут на самом деле делает я изменил это:

public class MemberDataSet 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public int? DeferredDataId { get; set; } 
    [ForeignKey("Id")] 
    public virtual DeferredData DeferredData { get; set; } 

    public int? SignedOffById { get; set; } 
    [ForeignKey("UserId")] 
    public virtual UserProfile SignedOffBy { get; set; } 
} 

Однако, сейчас я получаю очень похожее сообщение об ошибке:

The ForeignKeyAttribute on property 'SignedOffBy' on type 'MemberDataSet' is not valid. The foreign key name 'UserId' was not found on the dependent type 'MemberDataSet'. The Name value should be a comma separated list of foreign key property names. 

Разница здесь в том, что эта взаимосвязь - это много для одного, то есть 1 пользователь может иметь несколько наборов данных для подписания. В чем разница? то есть UserProfile теперь является основным объектом, поэтому ForeignKey находится в MemberDataSet?

Огромное спасибо за любую помощь.

+0

Вам не нужен атрибут 'ForeignKey'. EF передает его из имен. –

+0

Да, но разве это не означает, что я указал? – Mark007

ответ

0

Ошибка

The ForeignKeyAttribute on property 'DeferredData' on type 'MemberDataSet' is not valid. The foreign key name 'DeferredDataId' was not found on the dependent type 'DeferredData'.

говорит вам именно то, что это неправильно.

DeferredData.Id is not DeferredData.DeferredDataId 

Это ваша проблема.

Просто удаление атрибута решит вашу проблему, поскольку Entity Framework вычисляет внешние ключи на основе имени ваших объектов.Если вы хотите сохранить атрибуты, используйте:

[ForeignKey("Id")] 

вместо

[ForeignKey("DeferredDataId")] 

Итак:

public class MemberDataSet 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 

    public int? DeferredDataId { get; set; } 
    [ForeignKey("Id")] 
    public virtual DeferredData DeferredData { get; set; } 
} 

или изменить идентификатор DeferredData быть DeferredDataId и не Id

Несколько заметок о EF:

  1. свойства с именами Id автоматически ключи, поэтому нет необходимости для Key атрибута
  2. При определении отношения с помощью кода первых вам не нужно вручную украсить вещи с атрибутами, EF не фигурирует его на основе состав.

Edit:

Для связи один-ко-многим вам нужен ICollection<T>

public virtual ICollection<MemberDataSet> MemberDataSets { get; set; } 

ли UserProfile на UserId недвижимость?

+0

Спасибо. Я вижу здесь некоторую логику, но я все еще немного смущен. Я думал, что атрибут [ForeignKey («DeferredDataId»)] говорит, что свойство ForeignKey для моего навигационного свойства было свойством DeferredDataId для MemberDataSet. Разве это не так? – Mark007

+0

Нет, используя этот атрибут, вы заявляете, что ключ в 'DeferredData', который вы хотите использовать в качестве внешнего ключа в' MemberDataSet', называется 'DeferredDataId'. Он не называется 'DeferredDataId', он называется просто' Id'. –

+0

Хорошо, это начинает иметь смысл. Итак, каково значение публичного int? DeferredDataId {get; задавать; }? т.е. можно ли это удалить? Он подключен автоматически? и т.д. – Mark007