Blog Home  Home Feed your aggregator (RSS 2.0)  
artiso Blog - Listen effizient speichern mit LINQ to SQL
Neues rund um's Thema .Net
 
 Tuesday, September 18, 2007

Ich habe in einer Anwendung ein Objekt, das über ca. 30 List<double> Properties verfügt. Dieses Objekt möchte ich nun mit LINQ to SQL in die Datenbank schreiben. Natürlich unterstützt LINQ 1:n-Beziehungen in Objekten aber in der Datenbank müsste ich dann für jedes List-Property eine eigene Tabelle anlegen und für jedes Property einen eigenen Typ definieren. Das schien mir doch sehr umständlich.

Ich habe dann nach einer Möglichkeit gesucht, die List-Elemente etwas effizieter zu speichern, am einfachsten in einem Feld je Liste, da ich die für die Abfrage eh nicht brauche. Aber wie kann ich die Ausgabe von LINQ in die Datenbank steuern? Wie kann ich erreichen, dass LINQ meine Daten entsprechend formatiert?

Googeln brachte keine vernünftigen Ergebnisse und sonst bin ich auch nicht fündig geworden, aber dann kam die Idee (manchmal ist es schneller erst nachzudenken bevor man googelt, aber das vergisst man oft ;-)). Die Grundidee war, für jede Liste noch ein zusätzliches Property anlegen, das die Daten im Getter und Setter entsprechend formatiert. Die Hoffnung war, wenn ich dieses Property mit einem Column-Attribut versehe, wird LINQ den formatierten Inhalt schreiben und beim Lesen wieder zurückformatieren.

public List<string> Sales { get; set; }
[Column(Name="Sales", DbType = "nvarchar(4000)")]
private string SalesString
{
    get
    {
        return string.Join("|", Sales.ToArray());
    }
    set
    {
        if (value != null)
            Sales = value.Split('|').ToList();
    }
}

 

Ich habe einfach eine Text-Spalte in der Datenbank verwendet und die einzelnen List-Elemente mit einem Trennzeichen verbunden (der Einfachkeit halber habe ich mit einer List of Strings gearbeitet. Für die Tests ist das ausreichend und sollte auf beliebige andere Typen übertragbar sein).

Einen kleinen Stolperstein gibt es noch. Beim Ausführen erhielt ich folgende Meldung:

image

LINQ verwendet Optimistic Locking für das Schreiben und hat wohl Probleme, wenn der Inhalt des Property im Getter verändert wird. Abhilfe schafft hier das zusätzliche Attribut UpdateCheck, also sollte das Attribut zu dem Property so aussehen:

[Column(Name="Sales", DbType = "nvarchar(4000)", UpdateCheck=UpdateCheck.Never)]

 

Hier sind natürlich auch noch andere Möglichkeiten der Datenrepräsentation möglich. Hier mal ein Beispiel mit XML-Serialisierung und diesesmal auch mit Doubl-Werten.

public List<double> Sales { get; set; }
[Column(Name="Sales", DbType = "xml", UpdateCheck=UpdateCheck.Never)]
private string SalesString
{
    get
    {                
        UTF8Encoding encoding = new UTF8Encoding();
        MemoryStream ms = new MemoryStream();
        XmlSerializer xmlSer = new XmlSerializer(typeof(List<double>));
        xmlSer.Serialize(ms, Sales);
        return encoding.GetString(ms.ToArray());
    }
    set
    {
        if (value != null)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            MemoryStream ms = new MemoryStream(encoding.GetBytes(value));
            XmlSerializer xmlSer = new XmlSerializer(typeof(List<double>));
            Sales = (List<double>)xmlSer.Deserialize(ms);
        }
    }
}

 

Dank an Bernhard Gojer für den Lösungsansatz.

Tuesday, September 18, 2007 11:09:29 AM (Mitteleuropäische Zeit, UTC+01:00)  #    Comments [0]    |   | 
All comments require the approval of the site owner before being displayed.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Copyright © 2008 Thomas. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: