2013-03-05 5 views
17

Wie kann ich ein Array von Doubles mit Entity Framework Code-First in der Datenbank speichern, ohne dass dies Auswirkungen auf den vorhandenen Code und Architekturentwurf hat?So speichern Sie das double [] -Array in der Datenbank mit Entity Framework Code - Erster Ansatz

Ich habe Data Annotation und Fluent API angeschaut, ich habe auch überlegt, das Double-Array in eine Bytefolge umzuwandeln und dieses Byte in der Datenbank in seiner eigenen Spalte zu speichern.

ich nicht die public double[] Data { get; set; } Eigenschaft mit Fluent API zugreifen kann, mir die Fehlermeldung dann erhalten ist:

Der Typ double[] einen Nicht-Nullable-Wertetyp, um es als Parameter ‚T‘ zu verwenden sein muß .

Die Klasse, wo Data gespeichert wird in der Datenbank erfolgreich gespeichert ist, und die Beziehungen zu dieser Klasse. Ich vermisse nur die Data Spalte.

+0

Was repräsentiert die Daten? Vielleicht gibt es eine Möglichkeit, Ihren Code zu optimieren, damit alles funktioniert, ohne die Architektur zu sehr zu verändern. –

+0

Oder, für eine einfache Lösung, könnten Sie nicht eine kommagetrennte Zeichenfolge mit allen doppelten Werten erstellen, wenn Sie in die Datenbank schreiben, und dann die Zeichenfolge analysieren, wenn Sie die Werte benötigen? –

+0

@NathanWhite mit diesem Komma getrennte String-Ansatz gehen wir tatsächlich in Betracht ziehen. Aber wir möchten etwas automatisierter von EF.Wenn man die Antworten darauf in Betracht zieht, sagt man mir, dass es keine Möglichkeit gibt, ein Array von Doubles automatisch mit EF in die Datenbank zu bringen. Richtig? – jonas

Antwort

16

Vielen Dank für Ihre Eingaben, dank Ihrer Hilfe war ich in der Lage, die beste Lösung zu finden. Welches ist:

public string InternalData { get; set; } 
public double[] Data 
{ 
    get 
    { 
     return Array.ConvertAll(InternalData.Split(';'), Double.Parse);     
    } 
    set 
    { 
     _data = value; 
     InternalData = String.Join(";", _data.Select(p => p.ToString()).ToArray()); 
    } 
} 

Dank dieser Stackoverflow-Beiträge: String to Doubles array und Array of Doubles to a String

+1

Falls jemand sich fragt, muss 'InternalData' öffentlich sein, oder es ist nicht Teil des Datenbankschemas. Es kann auch sinnvoll sein, '' NotMapped] 'zum Attribut 'Data' hinzuzufügen, auch wenn dies unnötig ist. Dadurch wird deutlich, dass das Attribut nicht Teil des Datenbankschemas ist. –

36

Sie können wie folgt etwas tun:

[NotMapped] 
    public double[] Data 
    { 
     get 
     { 
      string[] tab = this.InternalData.Split(','); 
      return new double[] { double.Parse(tab[0]), double.Parse(tab[1]) }; 
     } 
     set 
     { 
      this.InternalData = string.Format("{0},{1}", value[0], value[1]); 
     } 
    } 

    [EditorBrowsable(EditorBrowsableState.Never)] 
    public string InternalData { get; set; } 
5

Ich weiß, es ist ein bisschen teuer, aber man konnte dies tun

class Primitive 
{ 
    public int PrimitiveId { get; set; } 
    public double Data { get; set; } 

    [Required] 
    public Reference ReferenceClass { get; set; } 
} 

// This is the class that requires an array of doubles 
class Reference 
{ 
    // Other EF stuff 

    // EF-acceptable reference to an 'array' of doubles 
    public virtual List<Primitive> Data { get; set; } 
} 

Dies wird nun eine einzelne Entität Karte (hier ‚Referenz ') zu einer' Liste 'deiner Primitiven Klasse. Dies ist im Grunde, um die SQL-Datenbank glücklich zu machen, und erlaubt Ihnen, Ihre Liste von Daten entsprechend zu verwenden.

Das mag zwar nicht Ihren Bedürfnissen entsprechen, aber es wird eine Möglichkeit sein, EF glücklich zu machen.

4

Es wäre viel einfacher, wenn Sie List<double> anstatt double[] verwenden. Sie haben bereits eine Tabelle, in der Ihre Data Werte gespeichert sind. Wahrscheinlich haben Sie einen Fremdschlüssel von einer Tabelle zur Tabelle, in der Ihre doppelten Werte gespeichert sind. Erstellen Sie ein anderes Modell, das die Tabelle widerspiegelt, in der Doubles gespeichert sind, und fügen Sie in der Mappings-Klasse Fremdschlüsselzuordnungen hinzu. Auf diese Weise müssen Sie keine komplexe Hintergrundlogik hinzufügen, die Werte in einer Klasseneigenschaft abruft oder speichert.

1

Nathan White hat die beste Antwort (habe meine Stimme).

Hier ist eine kleine Verbesserung gegenüber Antwort Joffrey Kern der Listen von beliebiger Länge zu ermöglichen (nicht getestet):

[NotMapped] 
    public IEnumerable<double> Data 
    { 
     get 
     { 
      var tab = InternalData.Split(','); 
      return tab.Select(double.Parse).AsEnumerable(); 
     } 
     set { InternalData = string.Join(",", value); } 
    } 

    [EditorBrowsable(EditorBrowsableState.Never)] 
    public string InternalData { get; set; }