2013-02-14 25 views
52

Wkrótce chcę utworzyć klucze złożone na moim stole pozostałe przy użyciu klucza podstawowego, aby poprawić wydajność wyszukiwania serwera sql. Problem z wydajnością występuje w tabeli danych 200k za każdym razem, gdy przeszukuję encję bez klucza podstawowego (tzn. Ciąg GUID). Załóżmy, że mam 3 klasyTworzenie struktury obiektu klucza złożonego

public class Device{ 

    public int ID { get; set; } 
    public string UDID { get; set; } 
    public string ApplicationKey { get; set; } 
    public string PlatformKey { get; set; } 

    public ICollection<NotificationMessageDevice> DeviceMessages { get; set; } 
} 

public class NotificationMessageDevice { 

    [Column(Order = 0), Key, ForeignKey("NotificationMessage")] 
    public int NotificationMessage_ID { get; set; } 

    [Column(Order = 1), Key, ForeignKey("Device")] 
    public int Device_ID { get; set; } 

    public virtual Device Device { get; set; } 
    public virtual NotificationMessage NotificationMessage { get; set; } 
} 

public class NotificationMessage { 

    public int ID { get; set; } 
    public string Text { get; set; } 
    public DateTime CreateDate { get; set; } 
} 

     modelBuilder.Entity<Device>().HasKey(t => new { t.ID, t.ApplicationKey, t.PlatformKey, t.UDID }); 

Jaki jest problem, że gdy chcę zrobić identyfikatora UDID, ApplicationKey i PlatformKey zdefiniować jako Composite Key z ModelBuilder daje następujący błąd.

NotificationMessageDevice_Device_Target_NotificationMessageDevice_Device_Source: : liczba właściwości w zależnych i głównym ról w związku przymusu muszą być identyczne

Myślę, że problemem jest fakt, że właściwość nawigacji na NotificationMessageDevice nie jest w stanie rozpoznać klucz podstawowy w tabeli urządzeń. Jak mogę rozwiązać ten problem? Oprócz tego będę zadowolony, jeśli podzielisz się swoimi doświadczeniami poprawiając wydajność wyszukiwania w strukturze Entity. Zwykle problem z wydajnością występuje zawsze, gdy używam metody pierwszej bez kluczy podstawowych.

+0

Nie jestem za dużo dla rozwoju EF, ale czy nie masz "ForeignKeyAttribute" na niewłaściwej rzeczy? –

+1

Nop ma rację :) – kkocabiyik

Odpowiedz

73

Jeśli Device tabela ma klucz podstawowy kompozytowego, to musisz sam kompozytowe klucza obcego w swojej NotificationMessageDevice tabeli. W jaki sposób SQL odnajdzie urządzenie bez pełnego klucza podstawowego? Powinieneś również ustawić te pola jako część klucza podstawowego tabeli NotificationMessageDevice. W przeciwnym razie nie możesz zagwarantować, że klucz podstawowy będzie unikalny:

public class NotificationMessageDevice 
{ 
    [Column(Order = 0), Key, ForeignKey("NotificationMessage")] 
    public int NotificationMessage_ID { get; set; } 

    [Column(Order = 1), Key, ForeignKey("Device")] 
    public int Device_ID { get; set; } 
    [Column(Order = 2), Key, ForeignKey("Device")] 
    public string Device_UDID { get; set; } 
    [Column(Order = 3), Key, ForeignKey("Device")] 
    public string Device_ApplicationKey { get; set; } 

    public virtual Device Device { get; set; } 
    public virtual NotificationMessage NotificationMessage { get; set; } 
} 
+0

Czy to konieczne, abyśmy zaimplementowali wszystkie właściwości zdefiniowane na kluczu złożonym, powinny być zaimplementowane w tabeli docelowej za każdym razem, gdy użyjemy obiektu Device jako właściwości nawigacji. – kkocabiyik

+0

Tak, to będzie klucz obcy w bazie danych. Klucz obcy jest kluczem podstawowym z tabeli nadrzędnej, więc powinien być dokładnie taki sam. Btw jeśli chcesz, aby 'PlatformKey' był częścią urządzenia PK, potrzebujesz tego pola w NotificationMessageDevice również –

+0

Hmm jeszcze jedno pytanie, czy istnieje sposób na stworzenie super klucza w Entity Framework? – kkocabiyik