Код сначала вызывает обязательное отношение, чтобы быть необязательным? - PullRequest
7 голосов
/ 04 декабря 2011
public class Client
{
    public Int32 ClientID { get; set; }

    public virtual ICollection<Inquiry> InquiryManufacturers { get; set; }
    public virtual ICollection<Product> Products { get; set; }
    public virtual ICollection<Inquiry> InquiryRetailers { get; set; }
}

public class Product
{
    public Int32 ProductID { get; set; }

    public Int32 ClientID { get; set; }
    public virtual Client Client { get; set; }

    public virtual ICollection<Inquiry> Inquiries { get; set; }
}

public class Inquiry
{
    public Int32 InquiryID { get; set; }

    public Int32 ProductID { get; set; }
    public Int32 ManufacturerID { get; set; }
    public Int32 RetailerID { get; set; }
    public virtual Product Product { get; set; }
    public virtual Client Manufacturer { get; set; }
    public virtual Client Retailer { get; set; }
}

Fluent Api имеет вид

HasRequired(i => i.Product)
  .WithMany(p => p.Inquiries);
HasRequired(i => i.Manufacturer)
  .WithMany(p => p.InquiryManufacturers)
  .HasForeignKey(p => p.ManufacturerID);
HasRequired(i => i.Retailer)
  .WithMany(p => p.InquiryRetailers)
  .HasForeignKey(p => p.RetailerID);

Итак, вот некоторые классы, которые я определил.Они имеют следующие отношения: клиент и продукт имеют один ко многим, клиент и запрос имеют один ко многим, а продукт и запрос имеют один ко многим.Я использую Code First здесь.Теперь, используя свободный API, я определил отношения, эти отношения должны быть обязательными, то есть отношения между клиентом и продуктом не могут быть нулевыми, равно как и клиент и запрос также не могут быть нулевыми.

Однако отношениямежду клиентом и запросом вынужден быть необязательным с первым кодом.Когда я пытаюсь сделать их обязательными, EF не создает базу данных.

Может ли кто-нибудь сказать мне, что не так с моей моделью, из-за которой EF не создает требуемые отношения между клиентом и Inruiry?Это из-за каскадного удаления?Как я читал, где mssql может иметь только один путь каскадного удаления между клиентом, продуктом и запросом.Любое объяснение помощи было бы хорошо.

1 Ответ

2 голосов
/ 08 января 2012

EF Code Сначала устанавливает каскадное удаление true для ограничения сгенерированного внешнего ключа по умолчанию. И поскольку у вас может быть только один каскадный путь, вы получаете исключение примерно так:

"Введение ограничения FOREIGN KEY 'Inquiry_Retailer' в таблицу «Запросы» могут вызывать циклы или несколько каскадных путей. Укажите ПО УДАЛИТЬ НЕТ ДЕЙСТВИЙ или ОБНОВИТЬ НЕТ ДЕЙСТВИЙ, или изменить другой КЛЮЧ ограничения.

В вашей модели у вас есть 3 каскадных пути от клиента к запросу:

Клиент - СправкаРейлеры -> Запрос
Клиент - ЗапросПроизводителей -> Запрос
Клиент - Продукты -> Продукт - Запросы -> Запрос

Так что вам нужно установить WillCascadeOnDelete(false) как минимум для двух отношений (в зависимости от ваших требований):

modelBuilder.Entity<Inquiry>().HasRequired(i => i.Product)
    .WithMany(p => p.Inquiries);
modelBuilder.Entity<Inquiry>().HasRequired(i => i.Manufacturer)
    .WithMany(p => p.InquiryManufacturers)
    .HasForeignKey(p => p.ManufacturerID).WillCascadeOnDelete(false);
modelBuilder.Entity<Inquiry>().HasRequired(i => i.Retailer)
     .WithMany(p => p.InquiryRetailers)
     .HasForeignKey(p => p.RetailerID).WillCascadeOnDelete(false);
...