ASP.NET EF从未映射的类中删除了鉴别器列

Lio*_*ion 14 c# asp.net inheritance entity-framework entity-framework-mapping

我有一个我的内容模型:

class BaseModel {
    public virtual string Content{ get; set; }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

要仅显示数据,上面的模型就可以了.但我想添加编辑内容的功能.所以我需要为成员内容添加一个属性- 但这只应该在autor按下编辑按钮时发生,而不是在内容的常规视图中.

所以我创建了第二个继承BaseModel的模型,以便我可以用我的属性覆盖成员:

class EditableBaseModel : BaseModel {
    [UIHint("MyEditor"), AllowHtml]
    public override string Content{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作,但由于继承,EF会创建一个额外的列鉴别器.它包含类的类型作为字符串.在我的情况下,它始终是BaseModel,因为我总是将EditableBaseModel转换为BaseModel,然后将它保存到数据库,如下所示:

myBbContextInstance.BaseModels.Add(editableBaseModelInstance as EditableBaseModel);
Run Code Online (Sandbox Code Playgroud)

因此,鉴别器列是浪费空间,我想删除它.我发现这可以使用NotMapped属性来完成.但是当我尝试保存模型时,这将导致以下异常:

无法找到EntityType'EditableBaseModel'的映射和元数​​据信息.

似乎NotMapped属性将让EF知道存在从BaseModel继承的另一个类,但EF不会获得有关此类的任何信息.但那不是我想要的.我需要告诉EF:EditableBaseModel不应该关心它,因为它只适合我的视图,并且永远不会用于数据库.

我怎样才能做到这一点?我发现的唯一方法是手动将EditableBaseModel实例转换为BaseModel对象,如下所示:

public ActionResult Save(EditableBaseModel editableBaseModel) {
    var baseModel = new BaseModel() {
        Content = editableBaseModel.Content
        // ...
    };
    myDbContextInstance.BaseModels.Add(baseModel);
}
Run Code Online (Sandbox Code Playgroud)

但这似乎不是一个很好的方法,因为我有多重属性.而且它也不是很灵活,因为当我向BaseModel添加内容时,我还必须在这里添加它 - 这可能会导致奇怪的错误.

Moh*_*our 8

EF概念与MVC概念混合成一个Model可能不适合两者.在这种情况下,创建新BaseModel内容并将内容复制EditableBaseModelBaseModel您的内容是正确的方法.您可以使用AutoMapper在两个模型之间映射数据.

class EditableBaseModel
{
    [UIHint("MyEditor"), AllowHtml]
    public string Content{ get; set; }
}

public ActionResult Save(EditableBaseModel editableBaseModel) {
    var baseModel = new BaseModel();
    Mapper.Map<EditableBaseModel, BaseModel>(editableBaseModel, baseModel);
    myDbContextInstance.BaseModels.Add(baseModel);
    .
    .
    .
}
Run Code Online (Sandbox Code Playgroud)


DDa*_*Dan 1

BaseModel您是否考虑过使用按以下方式工作的构造函数:

public BaseModel(EditableBaseModel editableBaseModel) {
    this.Content = editableBaseModel.Content
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

myBbContextInstance.BaseModels.Add(new BaseModel(editableBaseModelInstance));
Run Code Online (Sandbox Code Playgroud)