2013-02-14 20 views
52

In breve, desidero creare chiavi composite sul mio tavolo rimanendo con la chiave primaria per migliorare le prestazioni di ricerca di SQL Server. Il problema di prestazioni si verifica nella tabella di dati 200k ogni volta che cerco un'entità senza chiave primaria (cioè una stringa di GUID). Si supponga che ho 3 classiCreazione di Entity Framework composito

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 }); 

Quello che il problema è che ogni volta che voglio fare ID, UDID, ApplicationKey e PlatformKey definiscono come una chiave composta con ModelBuilder dà il seguente errore.

NotificationMessageDevice_Device_Target_NotificationMessageDevice_Device_Source: : Il numero di proprietà nei ruoli dipendenti e principale in una relazione di vincolo deve essere identico

Credo che il problema è perché la proprietà di navigazione sul NotificationMessageDevice non è in grado di riconoscere qual è la chiave primaria sulla tabella dei dispositivi. Come posso risolvere questo problema? Oltre a questo sarò lieto se condividi le tue esperienze migliorando il rendimento della ricerca su Entity framework. Di solito il problema di prestazioni si verifica ogni volta che utilizzo il primo metodo senza chiavi primarie.

+0

io non sono molto per lo sviluppo EF, ma non avete il 'ForeignKeyAttribute' sulla cosa sbagliata? –

+1

Nop proprio così :) – kkocabiyik

risposta

73

Se dispositivo tabella ha chiave primaria composta, allora avete bisogno stessa chiave esterna composta sul NotificationMessageDevice tavolo. In che modo SQL trova il dispositivo senza la chiave primaria completa? Inoltre, è necessario rendere questi campi come parte della chiave primaria della tabella NotificationMessageDevice. In caso contrario non è possibile garantire chiave primaria sarà unica:

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

È necessario che sia necessario implementare tutte le proprietà definite sulla chiave composita da implementare nella tabella di destinazione ogni volta che utilizziamo l'oggetto Dispositivo come proprietà di navigazione. – kkocabiyik

+0

Sì, questa sarà la chiave esterna nel database. La chiave esterna è una chiave primaria della tabella padre, quindi dovrebbe essere esattamente la stessa. Se vuoi che 'PlatformKey' sia parte del dispositivo PK, hai bisogno di quel campo in NotificationMessageDevice anche –

+0

Hmm un'altra domanda, c'è un modo per creare una chiave super su Entity Framework allora? – kkocabiyik