Entity Framework Code First List<string> 属性映射

25

我正在使用Entity Framework Code First。我有一个简单的模型:

public class Variable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public IList<string> TextOptions
    {
        get;
        set;
    }
}

我遇到了一个问题,即属性TextOptions的类型是List<String>

当我尝试在Entity Framework中执行此操作时,它无法映射。

我在这里(stackoverflow)找到了解决方案,可以解决我的问题。基本上,我重新构建了我的类,将列表转换为分隔字符串,然后进行持久化:

public class Variable : IVariable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public virtual IList<string> TextOptions
    {
        get
        {

            return _TextOptions;

        }
        set
        {
            _TextOptions = value;
        }
    }

    private IList<string> _TextOptions;

    public string TextOptionsSerialized
    {
        get
        {
            return String.Join(";", _TextOptions);
        }
        set
        {
            _TextOptions = value.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries).ToList();
        }
    }
}
这段代码运行良好。但我的问题是,我认为它违反了关注点分离原则。我认为我的模型类不应该关心将字符串列表序列化以便Entity Framework可以持久化。
我在使用ASP.Net MVC时遇到了类似的问题。我从客户端发送了一个帖子,该帖子将映射到一个模型。由于模型的结构与帖子不符,存在一些问题。在MVC中,我可以编写自定义模型绑定器以安全且可重用地处理转换。
是否有任何方法可以为Entity Framework做到像MVC的自定义模型绑定器一样干净?
2个回答

26

不,EF没有任何类型转换器或自定义类型映射器,作为MVC模型绑定器的替代品。您必须始终使用某些技巧来强制进行持久化。另一种做法是将TextOptions映射为相关实体的集合。它将使您的关注点分离更好,但会使您的模型和与Variable的工作变得更加复杂。

public class Variable
{
    public string Name { get; set; }

    public int Id { get; set; }

    public IList<TextOption> TextOptions
    {
        get;
        set;
    }
}

public class TextOption
{
    public int Id { get; set; }
    public string Text { get; set; }
}

2
感谢您的回复。虽然听到这个消息很难过!关于代码优先的整个声明似乎只是朝着正确方向迈出了半步。除非他们提供类似模型绑定器的东西,否则我无法创建与EF无关的模型。 - Mike Bynum
5
我想补充一下,你不能对EF感到失望,这是由于关系数据模型和面向对象数据模型之间固有差异所带来的限制。这是不同的概念。 - KellySandwiches
4
List<string>映射到具有idvalue的表格中,这个过程非常简单且常见,EF能否自动完成这个过程呢? - Matthijs Wessels
1
100万美元的务实问题:哪种方法能够产生更好的性能?序列化还是引入额外的实体? - Mauricio Aviles
@MauricioAviles 如果我回答了,你会给我100万美元吗?;) - JabberwockyDecompiler

7
第三种选择是使用JSON.NET进行序列化。
我进行了一些性能测试,使用此帖子中列出的3个选项(字符串拆分序列化、JSON.NET和引入实体)进行写入方案,并发现JSON.NET具有最佳性能。
200个相同实体的初步写入结果(在此查看源代码并运行测试):
- 使用字符串序列化程序编写实体的时间:896毫秒 - 使用JSON序列化程序编写实体的时间:516毫秒 - 使用多个实体编写实体的时间:706毫秒
使用JSON序列化程序的示例:
public class VariableJson
{
    public string Name { get; set; }

    public int Id { get; set; }

    public virtual IList<string> TextOptions
    {
        get
        {

            return _TextOptions;

        }
        set
        {
            _TextOptions = value;
        }
    }

    private IList<string> _TextOptions;

    public string TextOptionsSerialized
    {
        get
        {
            return JsonConvert.SerializeObject(_TextOptions);
        }
        set
        {
            _TextOptions = JsonConvert.DeserializeObject<IList<string>>(value);                    
        }
    }
}

4
请问当列表中只有2或3个字符串时,它们的相对表现是否不同?当列表中有一万个字符串时又是如何呢?请翻译此内容。 - Daniel Dyson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接