Po prostu najpierw używam kodu Entity Framework 4.1 i zamiast tego chciałbym zastąpić moje atrybuty [ForeignKey (..)] płynnymi wywołaniami w modelu ModelBuilder. Coś podobnego do WithRequired (..) i HasForeignKey (..) poniżej, które wiążą jawną właściwość klucza obcego (CreatedBySessionId) wraz z powiązaną właściwością nawigacji (CreatedBySession). Ale chciałbym to zrobić na jeden do jednego relationsip zamiast jednego do wielu:Kod EF 4.1 Najpierw ModelBuilder HasForeignKey dla pojedynczych relacji
modelBuilder.Entity<..>().HasMany(..).WithRequired(x => x.CreatedBySession).HasForeignKey(x => x.CreatedBySessionId)
Bardziej konkretnym przykładem jest poniżej. Działa to całkiem szczęśliwie za pomocą atrybutu [ForeignKey (..)], ale chciałbym go usunąć i skonfigurować go wyłącznie na modelbuilder.
public class VendorApplication
{
public int VendorApplicationId { get; set; }
public int CreatedBySessionId { get; set; }
public virtual Session CreatedBySession { get; set; }
}
public class Session
{
public int SessionId { get; set; }
[ForeignKey("CurrentApplication")]
public int? CurrentApplicationId { get; set; }
public virtual VendorApplication CurrentApplication { get; set; }
public virtual ICollection<VendorApplication> Applications { get; set; }
}
public class MyDataContext: DbContext
{
public IDbSet<VendorApplication> Applications { get; set; }
public IDbSet<Session> Sessions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Session>().HasMany(x => x.Applications).WithRequired(x => x.CreatedBySession).HasForeignKey(x => x.CreatedBySessionId).WillCascadeOnDelete(false);
// Note: We have to turn off Cascade delete on Session <-> VendorApplication relationship so that SQL doesn't complain about cyclic cascading deletes
}
}
Tutaj Sesja może być odpowiedzialny za tworzenie wielu VendorApplications (Session.Applications), ale sesja pracuje na co najwyżej jeden VendorApplication naraz (Session.CurrentApplication). Chciałbym powiązać właściwość CurrentApplicationId z właściwością nawigacji CurrentApplication w modelBuilder zamiast za pomocą atrybutu [ForeignKey (..)].
Czego próbowałem
Po wyjęciu [ForeignKey (..)] przypisują własnością CurrentApplication generuje kolumnę CurrentApplication_VendorApplicationId w bazie danych, który nie jest przywiązany do kolumny CurrentApplicationId.
Próbowałem jawnie mapowania relacji używając nazwy kolumny CurrentApplicationId jak poniżej, ale oczywiście to generuje błąd, ponieważ nazwa kolumny w bazie „CurrentApplicationId” jest już używana przez nieruchomości w Session.CurrentApplicationId:
modelBuilder.Entity<Session>().HasOptional(x => x.CurrentApplication).WithOptionalDependent().Map(config => config.MapKey("CurrentApplicationId"));
Czuję, że brakuje tu czegoś bardzo oczywistego, ponieważ wszystko, co chcę zrobić, to wykonać tę samą operację, którą wykonuje [ForeignKey (..)], ale w obrębie programu budującego model. Czy jest to przypadek, że jest to zła praktyka i została wyraźnie pominięta?
Tak, to jest to! Wcześniej grałem z tą konfiguracją, ale EF wyrzucił wyjątek dotyczący wielokrotności konfliktów, więc ustaliłem, że relacja musi wynosić 1: 1. Oczywiście teraz zdaję sobie sprawę, że konflikt mnogości faktycznie się wydarzył, ponieważ pierwotnie miałem CurrentApplicationId jako non-nullable ... ** (face palm) **. Dzięki za pomoc, bardzo docenione! – Walter