MartinHN
MartinHN

Reputation: 19772

EF Code First - Map Dictionary or custom type as an nvarchar

I want to use EF Code first for a database that I'm currently accessing using plain old ADO.NET with stored procedures.

In my database I have some nvarchar(MAX) columns that should be mapped to and from a Dictionary<string, string>.

When saved to database, it is an XML formatted string. I use this technique to allow internationalization of e.g. a name of a product in an online store. I don't know how many languages any given user want to translate to so I can't have a Name column for each language.

I also wanted to avoid storing the values in a seperate table, so I ended up with the Dictionary - XML approach.

The way I do it now, is to just treat any of these columns as a string whenever I interact with the database. I have a custom mapper function that can turn the XML into a Dictionary, and back to XML.

But I can't seem to find a way to do this with EF Code first? Any ideas?

Upvotes: 7

Views: 19207

Answers (2)

roland
roland

Reputation: 900

I had some difficulties with the xml conversion in VB.NET. Therefore I took advantage of newtonsoft.json to serialize the dictionary to a JSON string and back.

Public Property JsonDict As String
    Get
        If MyDict Is Nothing Then
            Return Nothing
        Else
            Return JsonConvert.SerializeObject(MyDict)
        End If
    End Get
    Set(value As String)
        If value Is Nothing Then
            MyDict = Nothing
        Else
            MyDict = JsonConvert.DeserializeObject(Of Dictionary(Of Single, Single))(value)
        End If
    End Set
End Property
<NotMapped>
Public Property MyDict As Dictionary(Of Single, Single)

Upvotes: 3

Wouter de Kort
Wouter de Kort

Reputation: 39888

You can add a property that will return your Dictionary<,> as a XML string and then remove the mapping for your Dictionary<,> property.

    [NotMapped]
    public Dictionary<string,string> MyDictionary
    {
     get; set;
    }

    public string DictionaryAsXml
    {
        get
        {
             return ToXml(MyDictionary);
        }
        set
        {
           MyDictionary = FromXml(value);
        }
    }

If you don't want to expose your DictionaryAsXml property have a look at this blog post. It shows how you can persist private and protected properties.

Upvotes: 16

Related Questions