I have a POCO (Plain Old CLR Object)
public Foo
{
public virtual int Id { get; set; }
public virtual Dictionary<string, string> Stuff { get; set; }
public virtual string More { get; set; }
}
Using the model first approach (i.e. I don't have a data model yet), how would I handle persisting Stuff (Dictionary)?
This is not a true answer to the question, but since there are no other replies, I'll share what I did.
I simply created a new type {Id, Code, Text}
and replaced my dictionary with a list of that type. I then do something like this to get the keys, values, or do a lookup:
List<string> texts = (from sv in q.SelectableValues select sv.Text).ToList();
List<string> codes = (from sv in q.SelectableValues select sv.Code).ToList();
string text = (from sv in q.SelectableValues where sv.Code == "MyKey" select sv.Text).First();
In my case the number of entries in the dictionary tends to be small. However, see this question for performance considerations when the dictionary/list is large.
It appears the generalized, correct way to persist a Dictionary to a database would be the way it's Enumerated, since tables are essentially Sets with a loose concept of order - just like IEnumerable. That is, a Dictionary is enumerated as IEnumerator< KeyValuePair< TKey, TValue > >, and so the table should have 2 columns:
Key
Value
From there you have the existing EF conventions of Complex Types, where Key might actually be an object with many properties, and value as well. For example a dictionary of user objects might look like:
Username (TKey)
Address1 (TValue)
Address2 (TValue)
It's unfortunate this generalized pattern isn't built-in to EF; it ought to be proposed.
Instead of developing a specific type for your solution, you could use a generalized class that produces a Data Annotated version of KeyValuePair<>.
public class EFKeyValuePair<TKey, TValue>
{
[Key]
public TKey Key { get; set; }
public TValue Value { get; set; }
}
I'm not certain how you'd ensure the table names would be written out in a logical and verifiable way however without inheriting this class and adding an attribute to each subclass. Perhaps the Fluent API could get you this final step (which I'm not very familiar with).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With