【问题标题】:Why is Entity Framework creating a discriminator column for my View Model?为什么实体框架为我的视图模型创建一个鉴别器列?
【发布时间】:2016-06-02 02:11:00
【问题描述】:

我刚刚阅读了很多关于 Table per Type/TPT 和鉴别器专栏的帖子,但是,在我的情况下,我并不是真的更聪明。

举个例子:我有一个 MVC 应用程序,它的模型名为 Foo。这有一个名为 Bar 的属性,它在其他地方以一对多的形式存储。

我是唯一一个使用这个应用程序的人,我不想花太多时间在它上面,所以我只想以最快的方式将项目添加到Bar 的列表中。因此,我创建了一个名为FooViewModel 的新类,它派生自Foo,并有一个名为BarTemp 的字符串属性。

基本思想是我可以在标准文本字段中输入111, 222 , 333,444,然后让编辑/创建控制器清除空格并拆分为逗号列表。

我想不通的是,视图模型永远不会被写入 EF,所以,它为什么要创建鉴别器列。

当我尝试构建迁移时,它似乎尝试将 BarTemp 添加到数据库中。

此后我创建了一个名为 same 的新类型,但我没有派生,而是将 FooBarTemp 作为其中的属性,它们可以按预期工作,但是,我仍然不明白发生了什么并且会想了解更多。

【问题讨论】:

    标签: c# asp.net-mvc entity-framework inheritance


    【解决方案1】:

    这是因为 EntityFramework 解析层次结构。仅仅因为您当前的代码从未保存过BarTemp,因此没有什么明确阻止您编写:

    context.Bars.Add(new BarTemp());
    

    EntityFramework 无法检测上述情况。因此,它很安全,并假设如果您从一个实体继承,您的子类是一个实体。这是一个正确的假设——你不应该让视图模型从实体继承。它们也不应该是财产。我真的不确定如何你已经设置了你当前的代码,但是这些类应该是完全不同的。例如,它应该看起来像:

    class BarTemp
    {
        public string BarId { get; set; }
        public string Foos { get; set; }
    }
    
    class Bar
    {
        public string BarId { get; set; }
        public ICollection<Foo> Foos { get; set; }
    }
    class Foo
    {
        public string Id { get; set; }
        public Bar Bar { get; set; 
    }
    

    您的视图模型应该对实体一无所知,而实体应该对视图模型一无所知。接受输入的代码应该完成将视图模型转换为实体的工作。例如:

    private void Update(BarTemp barTemp)
    {
        var bar = context.Bars.GetById(barTemp.BarId);
        foreach (var foo in barTemp.Foos.Split(","))
        {
            var foo = context.Foos.GetById(foo);
            bar.Foos.Add(foo);
        }
        context.Save();
    }
    

    不要把上面的例子当作好代码的例子——它效率极低——但它应该向你展示一个应该在哪里进行转换的例子,以及如何保持实体和视图模型分开。

    【讨论】:

    • 我仍然认为它在概念上很奇怪......我有一个类,我单独定义了该类的一个数据库集......我是从原始类派生的,而不是实体框架对象。我从来没有想过直接保存视图模型,这对我来说似乎很奇怪,但是,至少我现在明白了一点,所以,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2013-12-04
    • 2014-03-27
    相关资源
    最近更新 更多