2016-07-22 2 views
1

Я хочу, чтобы мой метод семя первым очистить/удалить базу данных и избавиться от всех старых данных, однакоКак очистить базу данных с ограничениями внешнего ключа?

context.Database.ExecuteSqlCommand("TRUNCATE TABLE [Purchases]"); 
context.Database.ExecuteSqlCommand("TRUNCATE TABLE [Invoices]"); 

дает мне

Не можете усечь таблицу «Закупки», так как он ссылается с помощью ограничения FOREIGN KEY.

поскольку записи в Покупках зависят от записей в Счетах. Как я могу очистить все данные с помощью метода семян?

редактировать: Это соответствующие модели:

public class Invoice 
{ 
    //Primary Key 
    public int InvoiceID { get; set; } 

    //Misc. info 
    public DateTime CreationDate { get; set; } 
    public DateTime DeadlineDate { get; set; } 
    public string ReceiverName { get; set; } 

    //Order details 
    public virtual List<Purchase> Purchases { get; set; } 

    //Auto-calculated property 
    [DataType(DataType.Currency)] 
    public float TotalCost { get; set; } 

    //Invoice author info 
    public string AuthorName { get; set; } 
    public string AuthorID { get; set; } 
} 


public class Purchase 
{ 
    public int PurchaseID { get; set; } 

    public string ProductDescription { get; set; } 

    public float SinglePrice { get; set; } 

    public float Amount { get; set; } 

    public float TotalPrice { get { return Amount * SinglePrice; } } 
} 

ответ

0

Существует несколько решений.

  1. Если вы хотите очистить всю базу данных, самым простым решением является только восстановление всей базы данных. Более сложным решением является сброс внешнего ключа, очистка базы данных и создание азата ключевых атак. Это может быть автоматизировано. Выполнение этого вручную не является хорошей идеей. Гораздо лучше перейти к следующему варианту.

  2. Зная структуру вашей базы данных, вы можете просто отбросить данные в порядке, который не будет нарушать ограничения внешнего ключа. Это также может быть автоматизировано, но с большими усилиями. Однако очень легко написать TRUNCE s в действующем порядке вручную.

    Не удается обрезать таблицу «Покупки», потому что на нее ссылается ограничение FOREIGN KEY.

    В этом случае в первую очередь определить, что таблица ссылок таблицы Purchases и чистые данные в этой таблице, прежде чем усечения Purchases.

    Также нет возможности удалить данные, не отбрасывая (или маркируя WITH NOCHECK) внешние ключи, если у вас есть ссылки на цикл.

  3. Вы также можете настроить удаление каскада, но я сильно против него, так как вы можете иногда удалять данные, которые вы бы не хотели удалять.

+0

Каскадное удаление сработало, спасибо. Я не пробовал это раньше, потому что это не позволило мне сделать цикл for на DbSet, и я думал, что вы не можете удалить членов запрошенной коллекции в цикле foreach, но я ошибся, по-видимому. Приветствия. – Simeon

0

Вам нужно будет очистить ваши таблицы в порядке ваших внешних ключей. Если в таблице «Покупки» указано ограничение внешнего ключа из «Счета-фактуры», вам необходимо сначала обрезать счета-фактуры.

1

Поскольку метод seed вызывается после обновления базы данных, я не думаю, что ваш метод будет работать. То, что я делал в прошлом, должно выполнить:

Update-Database -TargetMigration 0 

Это приведет к сбросу базы данных до первой миграции. Затем выполните:

Update-Database 
+0

ах хороший момент, я думал, что ему нужно сделать обрезку на производственной БД, я не понял, что это просто очистить шифер EF – RJB

+0

. Это будет выполнять методы понижения, но если данные были вставлены вне миграций, они не будут удалены. – lorond

+1

Один из методов 'Down' будет включать' DROP TABLE' ...., который удалит любые/все данные ..... – RJB

0

Если вы просто пытаетесь очистить данные повторно семена, agriffin правильно, просто использовать -Target-Migration:0 для сброса EF.

Если вы пытаетесь обрезать производственные данные, сначала необходимо сначала удалить ограничения внешнего ключа, а затем повторно добавить их после. На самом деле это не так.

Но сценарий в my other answer here быстро сгенерирует SQL-код ALTER TABLE, который необходимо добавить до и после вашего усечения. Я предлагаю сделать все это как часть хранимой процедуры:

ALTER TABLE [dbo].[Purchases] DROP CONSTRAINT.... 

TRUNCATE TABLE [Purchases]; 

ALTER TABLE [dbo].[Purchases] ADD CONSTRAINT.... 
Смежные вопросы