2016-10-02 5 views
1

Ich benutze Entity Framework 6 mit Table-Per-Type-Vererbung Ansatz.Woher kennt EF6 abgeleiteten Typ?

Tabellen wie folgt aussehen (nur ein Beispiel):

ConfigurationKeys 
    ID - int, not null, auto increment, primary 
    ConfigurationKeyType - int, not null 
    Key - varchar(50), not null 

StringConfigurationKeys 
    ID - int, not null, primary (foreign key to ConfigurationKey.ID) 
    StringValue - varchar(50), not null 

IntConfigurationKeys 
    ID - int, not null, primary (foreign key to ConfigurationKey.ID) 
    IntValue - int, not null 

und die folgenden Klassen Struktur:

public enum ConfigurationKeyType 
{ 
    StringConfigurationKey = 0, 
    IntConfigurationKey = 1 
} 

[Table("ConfigurationKeys")] 
public class ConfigurationKey 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    public ConfigurationKeyType ConfigurationKeyType { get; set; } 

    public string Key { get; set; } 
} 

[Table("StringConfigurationKeys")] 
public class StringConfigurationKey : ConfigurationKey 
{ 
    public string StringValue { get; set; } 
} 

[Table("IntConfigurationKeys")] 
public class IntConfigurationKey : ConfigurationKey 
{ 
    public int IntValue { get; set; } 
}  

Keine andere Konfigurationen und Modellbauer Zuordnungen vorgenommen werden.

Nun, wenn ich die folgende Abfrage tun:

var keys = context.ConfigurationKeys.ToArray(); 

Entity Framework gibt einen Array von abgeleiteten Typen.
i.e., keys[0] kann IntConfigurationKey und keys[1] vom Typ StringConfigurationKey sein. Ich kann es sicher umwandeln und auf Eigenschaften abgeleiteter Typen zugreifen.
Es ist ein großartiges Feature und ich liebe es, aber ich würde gerne wissen, wie es funktioniert, um diese Funktionalität in Zukunft zu erhalten.
Verwendet es enum oder sucht es nach einer Entität mit der gleichen ID in allen Tabellen?

Antwort

1

es Enum verwenden Hat oder es für eine sieht Entität mit der gleichen ID für alle Tabellen?

Mit TPT Strategie ist es LEFT OUTER JOIN s für alle bezogenen Tabellen verwenden, um die abgeleiteten Typ für die Bestimmung (und Daten). Es wird keine Diskriminatorsäule oder Ihr Enum verwendet.

Sie können dies sehen, indem Sie das generierte SQL anzeigen, indem Sie entweder die EF-Protokollierung aktivieren oder query.ToString() verwenden. Also beide

var sql = context.ConfigurationKeys.ToString(); 

oder

context.Database.Log = Console.WriteLine; 
var keys = context.ConfigurationKeys.ToArray(); 

wird so etwas wie diese zeigen:

SELECT 
    CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN '0X' WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN '0X0X' ELSE '0X1X' END AS [C1], 
    [Extent1].[ID] AS [ID], 
    [Extent1].[ConfigurationKeyType] AS [ConfigurationKeyType], 
    [Extent1].[Key] AS [Key], 
    CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS int) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN [Project1].[IntValue] END AS [C2], 
    CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS varchar(1)) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN CAST(NULL AS varchar(1)) ELSE [Project2].[StringValue] END AS [C3] 
    FROM [dbo].[ConfigurationKeys] AS [Extent1] 
    LEFT OUTER JOIN (SELECT 
     [Extent2].[ID] AS [ID], 
     [Extent2].[IntValue] AS [IntValue], 
     cast(1 as bit) AS [C1] 
     FROM [dbo].[IntConfigurationKeys] AS [Extent2]) AS [Project1] ON [Extent1].[ID] = [Project1].[ID] 
    LEFT OUTER JOIN (SELECT 
     [Extent3].[ID] AS [ID], 
     [Extent3].[StringValue] AS [StringValue], 
     cast(1 as bit) AS [C1] 
     FROM [dbo].[StringConfigurationKeys] AS [Extent3]) AS [Project2] ON [Extent1].[ID] = [Project2].[ID] 

ausführliche Erklärung kann in Inheritance with EF Code First: Part 2 – Table per Type (TPT) finden.

+0

Das ist die perfekte und vollständige Antwort auf meine Frage :) Danke. –

0

Standardmäßig verwendet EF die Strategie Tabelle pro Hierarchie, um die Datenbanktabellen zu erstellen. Ihre Klassen werden daher einer einzelnen Tabelle zugeordnet, und es wird eine Diskriminatorspalte vorhanden sein.

diesem Grund sollten Sie alle Daten aus verschiedenen Betonarten

zurück sehen Sie mehr über das Erbe in EF lesen zu können, folgen Sie diesem Link https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application

+0

Es verwendet Table-Per-Type-Strategie, weil ich jede Klasse mit 'Table' Attribut markiert haben, die EF6 jeden Typ an eine separate Tabelle teilt. –

+0

Sie haben also 3 Tabellen in der Datenbank gefunden? –

+0

Ja, genau :) Wenn ich Daten in Tabellen einfüge, erstellt es korrekt Basiselement mit automatisch generierten ID und abgeleitetes Objekt in einer untergeordneten Tabelle mit der gleichen ID. –

Verwandte Themen