实体框架4 POCO与字典

时间:2010-05-31 21:42:46

标签: dictionary entity-framework-4

我有一个POCO(普通旧CLR对象)

public Foo
{
   public virtual int Id { get; set; }
   public virtual Dictionary<string, string> Stuff { get; set; }
   public virtual string More { get; set; }
}

使用model first方法(即我还没有数据模型),我将如何处理持久的Stuff(字典)?

2 个答案:

答案 0 :(得分:8)

这不是问题的真实答案,但由于没有其他答复,我会分享我的所作所为。

我只是创建了一个新类型{Id, Code, Text},并将我的字典替换为该类型的列表。然后我做这样的事情来获取键,值或进行查找:

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

在我的情况下,字典中的条目数量往往很小。但是,当字典/列表很大时,请参阅this question以了解性能注意事项。

答案 1 :(得分:7)

似乎将字典持久化到数据库的通用,正确方法将是它的枚举方式,因为表本质上是具有松散的顺序概念的集合 - 就像IEnumerable一样。也就是说,字典被枚举为IEnumerator&lt; KeyValuePair&LT; TKey,TValue&gt; &gt;,因此该表应该有2列:

Key
Value

从那里你有复杂类型的现有EF约定,其中Key实际上可以是具有许多属性的对象,也是值。例如,用户对象的字典可能如下所示:

Username (TKey)
Address1 (TValue)
Address2 (TValue)

不幸的是,这种广义模式并非内置于EF;它应该被提议。

您可以使用生成KeyValuePair&lt;&gt;的数据注释版本的通用类,而不是为您的解决方案开发特定类型。

public class EFKeyValuePair<TKey, TValue>
{
    [Key]
    public TKey Key { get; set; }
    public TValue Value { get; set; }
}

我不确定如何确保以逻辑和可验证的方式写出表名,但是不继承此类并向每个子类添加属性。也许Fluent API可以为您提供最后一步(我不太熟悉)。