【问题标题】:Why is not possible to a view model inherit from Model in entity framework为什么视图模型不能从实体框架中的模型继承
【发布时间】:2014-05-30 13:25:57
【问题描述】:

当我在工作中开发应用程序时,出现错误:

Value cannot be null. Parameter name: input

有一个lots of post talking about that,所以我阅读了它们并且......没有解决方案。

很高兴继续。所以我检查了数据库模型中是否有任何属性不可为空试图插入而不是,所有这些属性都可以为空(身份除外),所以这不是问题。所以我意识到引发错误的 View Model 是从 Model 类继承,我想:“这可能是问题吗?”。所以我不再继承模型并重新开始工作。

请注意,这不是我第一次发生这种情况,两周前我遇到了同样的情况,就是因为它。

为什么我从模型类继承?因为它有 +10 属性,我需要它在视图中显示这些值,但我还需要显示来自另一个模型类的值,所以我创建了一个视图模型:

class ViewModel: ModelClass{

    //ModelClass contains +10 properties
    //and the current class contains 7 properties

    public ModelClass CastToModelClass()
    {
        return new ModelClass{ /*stuff...*/ }// casting the current properties values to the ModelClass class
    }
}

当我插入新铸造的模型时出现错误:

public JsonResult Save(ViewModel model)
{
    var modelClass = model.CastToModelClass();
    // here there are not empty properties
    context.ModelClass.Add(modelClass);
    context.SaveChanges();// error throw
}

所以我的问题是,为什么从 Model 类继承是错误的

【问题讨论】:

  • 您的 ViewModel 应该与您的模型分开(即在此上下文中的实体)。请记住,“ViewModel”是 视图的模型。换句话说,它可以显示原始模型的相同、紧凑或转换的信息。您是否尝试过通过 ViewModel 的构造函数传入模型类的实例?这就是我的方法,而且效果很好。我很乐意提供一个例子。
  • @MarioJVargas 是的,这也是我的方法(也是我能找到的最佳解决方案)。你能解释一下你在这里说的话吗:“你的 ViewModel 应该与你的模型分开(即在这种情况下的实体)。记住“ViewModel”是视图的模型”。我很想知道这意味着什么。
  • 视图模型正是它所说的,它是视图显示的模型。您的另一个模型是域模型,这是数据库关心的东西。我们使用视图模型来改变域模型在视图上的呈现方式。
  • 你不能直接插入你的视图模型。您必须将其映射回基类(即域模型)才能做到这一点。出于理智考虑,我建议为此目的使用 AutoMapper 之类的东西。
  • @Yuck 说得好。但是我没有直接插入我的视图模型,也没有对 ModelClass 进行强制转换,而是从 ViewModel 类的值创建了一个全新的 ModelClass 实例。但我明白了。

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


【解决方案1】:

modelview model 是两个不同的概念。模型与应用程序的业务逻辑相关,而视图模型是该模型与视图的直接适配器(因此,视图模型)。

此外,尽管它们可能共享一些属性和功能,但视图模型将根据需要在视图中呈现的内容的需求而发展;在某些情况下,您将拥有与单个模型相关的多个视图模型。

在您的示例中,您已经尝试通过以下方式将视图模型转换为模型,

var modelClass = model.CastToModelClass();

这本身就是一个断言,您正在处理两个不同的概念。模式本身(返回具有给定属性集的模型类)还不错;但是,完全没有必要从模型类继承。

class ViewModel : ModelClass // <-- Remove inheritance

【讨论】:

    【解决方案2】:

    您的问题“为什么错误地从模型类继承?”来自错误假设这个问题是由继承引起的。这样做在概念上是不可取的,但从技术上讲,如果编程正确,它不会引起任何问题。

    其他人已经回答了为什么将实体框架模型用作(部分)视图模型不是一个好主意,所以我将解决手头的技术问题。

    如果你这样做:

    var modelClass = model.CastToModelClass();
    context.ModelClass.Add(modelClass);
    context.SaveChanges();
    

    CastToModelClass() 返回一个 EF 模型,使您的继承问题无关紧要。问题必须出在准备并返回新的ModelClass 实体的代码中。

    如果你这样做

    var entityModel = new ModelClass
    {
        Prop1 = model.Prop1,
        Prop2 = model.Prop2,
        // ...
    };
    context.ModelClass.Add(entityModel);
    context.SaveChanges();
    

    你基本上也是这样做的。那应该行得通;如果没有,则您没有正确映射所有属性。问题不在于继承。

    【讨论】:

    • 从 EF Core 3.0 开始,将模型的子类添加到 db 上下文会导致插入一个空对象。
    猜你喜欢
    • 2017-09-04
    • 2011-05-29
    • 2016-03-26
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多