2013-03-05 18 views
17

Jak mogę przechowywać tablicę podwójnych danych do bazy danych za pomocą Entity Framework Code-First bez wpływu na istniejący kod i architekturę?Jak przechowywać podwójną tablicę [] do bazy danych za pomocą Entity Framework Code-First approach

Przyjrzałem się Adnotacji danych i Fluent API, rozważałem również konwersję podwójnej tablicy na ciąg bajtów i zapisanie bajta do bazy danych w jej własnej kolumnie.

Nie można uzyskać dostępu do właściwości public double[] Data { get; set; } z Fluent API, komunikat o błędzie I wtedy pojawia się:

Typ double[] musi być typ wartości spoza zerowalne w celu korzystania go jako parametru „T” .

Klasa, w której przechowywane jest Data, jest pomyślnie przechowywana w bazie danych i relacje z tą klasą. Brakuje mi tylko kolumny Data.

+0

Jakie dane reprezentują? Może istnieje sposób na ulepszenie kodu, aby wszystko działało bez zbytniej zmiany architektury. –

+0

Lub, dla prostej poprawki, nie można utworzyć ciągu oddzielonego przecinkami z wszystkimi podwójnymi wartościami podczas zapisywania do bazy danych, a następnie przeanalizować ciąg znaków, gdy potrzebujesz wartości? –

+0

@NathanWhite z tym podejściem łańcuchowym oddzielonym przecinkami jest czymś, co faktycznie rozważamy. Ale chcielibyśmy coś bardziej automatycznego z EF.Biorąc pod uwagę odpowiedzi na to, powiedziałem, że nie ma sposobu, aby automatycznie podać tablicę podwójną do bazy danych za pomocą EF. Poprawny? – jonas

Odpowiedz

16

Dziękuję za wszystkie uwagi, dzięki Twojej pomocy udało mi się znaleźć najlepszy sposób rozwiązania tego problemu. Który jest:

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

Dzięki tym StackOverflow postów: String to Doubles array i Array of Doubles to a String

+1

Jeśli ktoś się zastanawia, 'InternalData' musi być publiczny lub nie będzie częścią schematu bazy danych. Dobrym pomysłem może być dodanie '[NotMapped]' do atrybutu 'Data', nawet jeśli nie jest to konieczne. To wyjaśnia, że ​​atrybut nie jest częścią schematu bazy danych. –

36

można zrobić coś takiego:

[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

wiem, że to jest trochę drogie, ale można to zrobić

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

To będzie teraz mapować jeden podmiot (tutaj „Reference ') do "listy" twojej prymitywnej klasy. Zasadniczo pozwala to na zadowolenie bazy danych SQL i pozwala na właściwe wykorzystanie listy danych.

To może nie odpowiadać twoim potrzebom, ale będzie sposobem na sprawienie, że EF będzie szczęśliwy.

4

Byłoby znacznie łatwiej, jeśli używasz List<double> zamiast double[]. Masz już tabelę, która przechowuje wartości Data. Prawdopodobnie masz klucz obcy z pewnej tabeli do tabeli, w której przechowywane są twoje podwójne wartości. Stwórz inny model, który odzwierciedla tabelę, w której są przechowywane duble i dodaj odwzorowania kluczy obcych w klasie odwzorowań. W ten sposób nie trzeba dodawać skomplikowanej logiki tła, która pobiera lub przechowuje wartości we właściwości klasy.

1

Nathan White najlepszą odpowiedź (dostał mój głos).

Oto niewielka poprawa w odpowiedzi Joffrey Kerna, aby umożliwić list o dowolnej długości (nietestowanego):

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