2017-04-05 39 views
8

z następującymi modelami jeden do jednego, zarówno o właściwościach nawigacji: -EF - WithOptional - Left Outer Join?

public class Foo 
{ 
    public int Id { get; set; } 

    public virtual Bar Bar { get; set; } 
} 

public class Bar 
{ 
    public int Id { get; set; } 

    public virtual Foo Foo { get; set; } 
} 

Foo ma opcjonalny Bar.

Bar ma wymagane Foo.

Mam następujące mapowania na Bar: -

HasRequired(x => x.Foo) 
     .WithOptional(x => x.Bar) 
     .Map(x => x.MapKey("FooId")); 

który tworzy klucz obcy na Bar tabeli o nazwie 'FooId'.

Wszystko to działa dobrze, poza tym, że generuje SQL dla Foo z „Left Outer Join” do Bar na wszystkie zapytania, gdy jej nie potrzeba.

SELECT .. 
[Extent2].[Id] AS [Id1] 
FROM [dbo].[Foo] AS [Extent1] 
LEFT OUTER JOIN [dbo].[Bar] AS [Extent2] ON [Extent1].[Id] = [Extent2].[FooId] 

Przyjrzyj się bliżej, tylko zwraca identyfikator paska.

Searching stos Widzę większość propozycji użycia .WithMany zamiast .WithOptional, ale potrzebuję właściwości nawigacji.

Wszelkie sugestie?

+0

Jeśli myślisz o tym, nie ma czegoś takiego jak 1: 1, chyba że robisz wspólny klucz podstawowy, ponieważ klucze muszą być unikatowe ze względu na swój charakter. Oczywiście, możesz ustawić unikalne ograniczenie na 1: *, aby stworzyć efektywny 1: 1, ale jest to rodzaj "wirtualnego" 1: 1, a nie rzeczywistego fizycznego.EF nie obsługuje takich ograniczeń, więc nie jest to możliwe. Właśnie dlatego dołączenie jest tam, ponieważ EF może założyć, że jest to 1: * –

Odpowiedz

4

Jest to standardowe zachowanie dla powiązania FK jeden-do-jednego i nie można go uniknąć. Co EF robi, to wewnętrznie ukryć ukrytą (cień) właściwość, taką jak int? BarId dla jednostki .

Jedynym sposobem, aby pozbyć się LEFT OUTER JOIN s oraz zachować dwukierunkowych właściwości nawigacyjnych jest, jeśli może sobie pozwolić zmieniając model Bar db (tabela) używać (domyślnie EF modelu jeden-na-jeden) Shared Primary Key Association przez zasadzie wyjmowania Map wezwanie z płynną konfiguracji:

HasRequired(x => x.Foo) 
    .WithOptional(x => x.Bar); 

W tym modelu tabela Bar nie będzie zawierała FooId kolumny FK, ale zamiast kolumna PK Id więcej nie będzie tożsamość i będzie służyć również jako FK przedstawieniu Foo tabl mi.

Pozwala EF nie obchodzi utrzymanie BarId w Foo ponieważ wie, że jeśli istnieje odpowiadający Bar, byłoby z Id same jak Foo.Id.

Jeśli nie możesz zmienić projektu bazy danych, oznacza to, że masz pecha - musisz albo żyć z LEFT OUTER JOIN s, albo poświęcić właściwość nawigacji Foo.Bar i skonfigurować relację jako jednokierunkowy jeden-do-wielu, tak jak już wzmiankowany.