Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET EF从未映射类中删除鉴别器列_C#_Asp.net_Entity Framework_Inheritance_Entity Framework Mapping - Fatal编程技术网

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

C# ASP.NET EF从未映射类中删除鉴别器列,c#,asp.net,entity-framework,inheritance,entity-framework-mapping,C#,Asp.net,Entity Framework,Inheritance,Entity Framework Mapping,我有一个我的内容模型: class BaseModel { public virtual string Content{ get; set; } // ... } 要仅显示数据,可以使用上面的模型。但是我想添加编辑内容的功能。因此,我需要为成员内容添加一个属性——但这应该只在自动按下编辑按钮时发生,而不是在内容的常规视图中 因此,我创建了第二个模型,该模型继承自BaseModel,以便我可以使用我的属性覆盖该成员: class EditableBaseModel : BaseM

我有一个我的内容模型:

class BaseModel {
    public virtual string Content{ get; set; }
    // ...
}
要仅显示数据,可以使用上面的模型。但是我想添加编辑内容的功能。因此,我需要为成员内容添加一个属性——但这应该只在自动按下编辑按钮时发生,而不是在内容的常规视图中

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

class EditableBaseModel : BaseModel {
    [UIHint("MyEditor"), AllowHtml]
    public override string Content{ get; set; }
}
这很好,但是由于继承EF创建了一个额外的列鉴别器。它以字符串形式包含类的类型。在我的例子中,它总是BaseModel,因为在保存到数据库之前,我总是将EditableBaseModel转换为BaseModel,如下所示:

myBbContextInstance.BaseModels.Add(editableBaseModelInstance as EditableBaseModel);
myBbContextInstance.BaseModels.Add(new BaseModel(editableBaseModelInstance));
因此,鉴别器列是对空间的浪费,我想删除它。我发现这是可以做到的。但当我尝试保存模型时,这将导致以下异常:

找不到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);
}

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

您是否考虑过在
BaseModel
中使用构造函数,其工作方式如下:

public BaseModel(EditableBaseModel editableBaseModel) {
    this.Content = editableBaseModel.Content
}
然后像这样使用它:

myBbContextInstance.BaseModels.Add(editableBaseModelInstance as EditableBaseModel);
myBbContextInstance.BaseModels.Add(new BaseModel(editableBaseModelInstance));

EF
概念与
MVC
概念混合到
模型中可能不适合两者。在这种情况下,创建新的
BaseModel
并像您那样将
EditableBaseModel
的内容复制到
BaseModel
是正确的方法。可以用于在两个模型之间映射数据

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);
    .
    .
    .
}
类EditableBaseModel
{
[UIHint(“MyEdit”),AllowHtml]
公共字符串内容{get;set;}
}
公共操作结果保存(EditableBaseModel EditableBaseModel){
var baseModel=新的baseModel();
Mapper.Map(editableBaseModel,baseModel);
myDbContextInstance.BaseModels.Add(baseModel);
.
.
.
}

底线是,在实体框架中使用继承,您不能用两种不同的类型来表示数据库中的同一条记录

换句话说,如果以任何方式使用继承,EF可以将数据库中的任何行具体化为一种类型。所以,无论有没有鉴别器,你想要的永远都是不可能的

我认为与
EditableBaseModel
之间的转换是一个可行的选择。或者将
BaseModel
包装在
EditableBaseModel
中,后者具有委托属性,如

public string Content
{ 
    [UIHint("MyEditor"), AllowHtml]
    get { return _baseModel.Content; }
    set { _baseModel.Content = value; }
}
这是一种常见的模式,称为Decorator。请注意,在这种情况下(或转换时),您不应将
EditableBaseModel
注册为EF模型中的实体

从技术上讲,另一种方法是可能的。您可以通过以下方式具体化任何对象。您可以将
BaseModel
仅用于显示目的,并将
EditableBaseModel
用作映射的实体类<代码>基本模型
s则可以通过

myBbContextInstance.Database.SqlQuery<BaseModel>("SELECT * FROM dbo.BaseModel");
myBbContextInstance.Database.SqlQuery(“从dbo.BaseModel中选择*);
当然,查询可以参数化以过滤模型。
BaseModel
s将不会被上下文跟踪,但由于您只想显示它们,因此不需要这样做。这是我看到的用另一种类型表示(排序)数据库中一条记录的唯一方法


虽然我提到了技术上的可能性,但这并不意味着我推荐它。但是,即使对于“可编辑”选项,我也更喜欢使用视图模型。我不喜欢数据层和UI之间的这种紧密耦合。

为什么不在BaseModel中添加一个非映射的布尔字段,这将表明用户希望更改内容?因为我使用UIHint属性插入部分视图,就像我的编辑器中的部分视图一样。似乎无法在运行时设置此属性。属性是按类设置的,而不是按实例设置的。在我看来,您可以在局部视图中使用一个条件,该条件基于一个标志字段,将显示或隐藏编辑控件属性到
EditableBaseModel
?是的,我尝试了一个类似的解决方案,在EditableBaseModel中放置了一个名为ToBaseModel的方法,该方法返回一个BaseModel实例。它可以工作,但我不喜欢这个解决方案,因为当我更改模型时,我还必须将属性添加到转换器方法中。所以我更喜欢像类型转换这样的自动化解决方案,但不幸的是这不起作用。我明白了。我在考虑构造函数,因为每当有人更改模型时,都会知道构造函数也必须更改,但是是的,自动化程度不高。。。