为什么Entity Framework为我的View Model创建一个鉴别器列?

时间:2016-06-02 02:11:00

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

我刚刚在Table per Type / TPT和歧视者专栏上阅读了不少帖子,但是,在我的情况下,我并不是真的更聪明。

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

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

基本思想是我可以在标准文本字段中键入111, 222 , 333,444并让编辑/创建控制器清除空白并分成逗号上的列表。

我能弄清楚的是,视图模型永远不会写入EF,因此,为什么要创建鉴别器列。

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

我已经创建了一个名为相同的新类型,但是我只是将FooBarTemp作为属性,而不是派生,而是按预期工作,但是,我仍然没有'了解发生的事情,并希望了解更多。

1 个答案:

答案 0 :(得分:2)

这是因为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();
}

不要将上述内容作为优秀代码的示例 - 效率极低 - 但它应该向您展示转换应在何处发生的示例,以及如何保留实体和查看模型分开。