Проблемы каскадного удаления Entity Framework - для внешнего ключа установлено значение null - PullRequest
2 голосов
/ 31 марта 2010

У меня есть следующая модель, которую я сопоставил с Entity Framework: Mitglied -> Auftrag -> Teilprojekt

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

Mitglieder m1 = new Mitglieder();
m1.Name = "erstes";

Auftraege a1 = new Auftraege();
a1.Name = "a1";
m1.Auftraege.Add(a1);

Teilprojekte t1 = new Teilprojekte();
t1.Name = "t1";
a1.Teilprojekte.Add(t1);

context.AddToMitglieder(m1);


Mitglieder m2 = new Mitglieder();
m2.Name = "zweites";

Auftraege a2 = new Auftraege();
a2.Name = "a2";
m2.Auftraege.Add(a2);

Teilprojekte t2 = new Teilprojekte();
t2.Name = "t2";
a2.Teilprojekte.Add(t2);

context.AddToMitglieder(m2);
context.SaveChanges();

Это правильно добавляет все объекты и устанавливает внешние ключи. Если я затем выполню следующий код для удаления Auftraege:

 var members = context.Mitglieder.ToList();

 var mem1 = members.Single(m => m.Name == "erstes");
 mem1.Auftraege.Load();
 var auf1 = mem1.Auftraege.First();
 context.DeleteObject(auf1);

 var mem2 = members.Single(m => m.Name == "zweites");
 mem2.Auftraege.Load();
 var auf2 = mem2.Auftraege.First();

 //THIS IS THE LINE THAT MAKES THE DIFFERENCE
 auf2.Teilprojekte.Load();

 context.DeleteObject(auf2);

 context.SaveChanges();

Два Auftraege a1 и a2 правильно удалены; также Teilprojekt t1 удаляется, но Teilprojekt t2 не удаляется;

Для его столбца AuftragID установлено значение NULL!

Разница лишь в том, что для a1 я не загружал Teilprojekte, а для a2 я их загружал. Я не понимаю, почему это не работает должным образом. Также в SSDL все настроено правильно:

    <Association Name="FK_Auftraege_Mitglieder">
      <End Role="Mitglieder" Type="TechnBuero.Store.Mitglieder" Multiplicity="0..1">
        <OnDelete Action="Cascade" />
      </End>
      <End Role="Auftraege" Type="TechnBuero.Store.Auftraege" Multiplicity="*" />
      <ReferentialConstraint>
        <Principal Role="Mitglieder">
          <PropertyRef Name="ID" />
        </Principal>
        <Dependent Role="Auftraege">
          <PropertyRef Name="Mitglieder_ID" />
        </Dependent>
      </ReferentialConstraint>
    </Association>
    </Association>
        <Association Name="FK_Teilprojekte_Auftraege">
      <End Role="Auftraege" Type="TechnBuero.Store.Auftraege" Multiplicity="0..1">
        <OnDelete Action="Cascade" />
      </End>
      <End Role="Teilprojekte" Type="TechnBuero.Store.Teilprojekte" Multiplicity="*" />
      <ReferentialConstraint>
        <Principal Role="Auftraege">
          <PropertyRef Name="ID" />
        </Principal>
        <Dependent Role="Teilprojekte">
          <PropertyRef Name="AuftragsID" />
        </Dependent>
      </ReferentialConstraint>
    </Association>

Если я установлю AuftragsID в таблице Teilprojekte не равным NULL, тогда я получу следующую ошибку из Entity Framework:

Error 1 Error 3023: Problem in Mapping Fragments starting at lines 638, 702: Column Teilprojekte.AuftragsID has no default value and is not nullable. A column value is required to store entity data. 
An Entity with Key (PK) will not round-trip when:
((PK is in 'Teilprojekte' EntitySet OR PK plays Role 'Teilprojekte' in AssociationSet 'FK_Teilprojekte_Auftraege') AND (PK is NOT in 'Teilprojekte' EntitySet OR PK does NOT play Role 'Teilprojekte' in AssociationSet 'FK_Teilprojekte_Auftraege'))

Может кто-нибудь помочь мне и сказать, что происходит не так и как я могу решить эту проблему? Спасибо

1 Ответ

2 голосов
/ 02 апреля 2010

Каскадное удаление в EDMX будет каскадно загружать (прикреплять) объекты. поэтому, если ваша сущность не загружена, она не будет каскадно удалять. EF ожидает от вашей базы данных каскадного удаления.

  1. Убедитесь, что в вашей базе данных настроено каскадное удаление
  2. Установите каскадное удаление в вашем EDMX
  3. Если вы не можете сделать 1, убедитесь, что вы загрузили все объекты перед удалением
...