【问题标题】:Entity Framework Code First List<string> Property Mapping实体框架代码优先列表<string> 属性映射
【发布时间】:2012-01-09 04:55:28
【问题描述】:

我首先使用实体​​框架代码。我有一个简单的模型:

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

    public int Id { get; set; }

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

我遇到了属性TextOptions 的类型为List&lt;String&gt; 的问题。

当我尝试在 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();
        }
    }
}

此代码运行良好。我遇到的问题是我认为它违反了关注点分离。我认为我的模型类不应该关注序列化字符串列表以便实体框架可以持久化它。

我在 ASP.Net MVC 中遇到了类似的问题。我有一个从客户端发送的帖子,该帖子将被映射到一个模型。与帖子相比,模型的结构方式存在一些问题。在 MVC 中,我可以编写一个自定义模型绑定器来以一种非常安全和可重用的方式处理转换。

有没有什么方法可以让实体框架像 MVC 的自定义模型绑定器一样干净?

【问题讨论】:

    标签: entity-framework model mapping


    【解决方案1】:

    不,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; }
    }
    

    【讨论】:

    • 感谢您的回复。虽然很遗憾听到它!整个关于代码的主张似乎只是朝着正确方向迈出了半步。我无法创建与 EF 无关的模型,除非它们提供模型绑定器之类的东西。
    • 我只是想补充一点,您不会对 EF 感到失望。这是关系数据模型和面向对象数据模型之间的内在差异带来的限制。不同的概念。
    • @KellySandwiches 从List&lt;string&gt; 到带有idvalue 的表的映射非常简单和常见,它可以由EF 自动完成,对吧?
    • 价值 100 万美元的务实问题:哪种方法会产生更好的性能?序列化或引入额外的实体>
    • @MauricioAviles 如果我回答,你会给我 100 万美元吗?)?
    【解决方案2】:

    第三种选择是使用 JSON.NET 进行序列化。

    我使用此线程中列出的 3 个选项(字符串拆分序列化、JSON.NET 和引入实体)对写入场景进行了一些性能测试,发现 JSON.NET 产生了最佳性能。

    200个相等实体的初步写入结果(see source code here and run the test yourself):

    • 使用字符串序列化器写入实体的时间: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);                    
            }
        }
    }
    

    【讨论】:

    • 我想知道如果您的列表中只有 2 个或 3 个字符串,相对性能是否会有所不同。一万个呢?
    猜你喜欢
    • 1970-01-01
    • 2011-08-06
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多