从基类访问子类的字段

时间:2011-07-13 08:35:09

标签: asp.net-mvc-3

我不知道是否可以这样做。我有两个班:

public class Document
    {
  public uint location;

    public Document(uint documentId)
    {
        // Here complex logic of retrieving information from DB follows
        OracleCommand documentCommand = new OracleCommand("select field1, field2, field3 from table(usr.common_pck.GetDocument(:pDocumentId))", conn);
        documentCommand.Parameters.Add("pDocumentId", documentId);
        OracleDataReader documentReader = documentCommand.ExecuteReader();
        if (documentReader.HasRows)
        {
            this.id = documentId;
            this.serial = documentReader.GetString("field2");
            this.location = Convert.ToUInt32(documentReader.GetInt32("field1"));    
            // Here I want to call "manualSetLocationStr(field3)" of DocumentViewModel
        }
    }
}

这里有第二堂课:

     public class DocumentViewModel : Document {
            private OracleConnection connection;
            private string _locationStr { get; set; }

            protected void manualSetLocationStr(string value)
            {
                _locationStr = value;
            }

            public string typeStr { get { return ((Dictionary<int, string>)HttpContext.Current.Application["DocumentTypesList"]).Single(mbox => mbox.Key == type).Value; } }

public string locationStr { 
                get {
                    if (_locationStr == null) {
                        OracleCommand getNameCommand = new OracleCommand("select usr.common_pck.GetName(:id) as name from dual", connection);
                        getNameCommand.Parameters.Add("id", this.location);
                        OracleDataReader NameReader = getNameCommand.ExecuteReader();
                        NameReader.Read();
                        _locationStr = NameReader.GetString("name");
                    }
                    return _locationStr;
                } 
            }    
        }

所以我的问题是如何在Document的构造函数中调用manualSetLocationStr()?我需要这样做以避免第二次从locationStr get访问器中的数据库中检索信息,因为我已经拥有它(这是Document构造函数中的field3)。 任何建议,任何建议,将非常感激。 非常希望得到你的帮助! 提前谢谢!

2 个答案:

答案 0 :(得分:1)

为什么field3值不能存储为Document的属性?此外,视图模型更适合包含其模型的实例,而不是从它们派生。

<强>更新

这取决于您的体系结构,但您可以创建一个DocumentInfo类型,例如具有视图所需的所有属性。然后,您需要为视图填充这些集合,您可以使用DocumentInfoRepository来提供数据访问的抽象。可以直接在您的实体中或从您的控制器访问此存储库,具体取决于您的域模型类型和您希望使用的模式。

答案 1 :(得分:0)

看看你如何在视图模型类上拥有OracleConnection属性 - 它似乎是错误的。假设您已经创建了DocumentViewModel类,我强烈建议您在控制器中填充它并从中省略OracleCOnnection。您可以使用AutoMapper来映射它,而不是继承自Document。这涉及两个简单的步骤:

每个应用程序启动时执行一次:

AutoMapper.Mapper.CreateMap<Document, DocumentViewModel>();

然后在控制器中使用它:

var viewModel = AutoMapper.Mapper.Map<Document, DocumentViewModel>(documentInstance);

这将创建DocumentViewModel的实例并尽可能多地映射属性。通过这样做,您可以满足继承Document类的需要。

至于视图模型的结构。而不是使用方法typeStr,而是具有在控制器操作中自动映射之后设置的属性TypeStr。您的typeStr方法也是如此。

视图模型的整体思想是为UI提供尽可能多的表示要呈现的数据。理想情况下,没有方法调用,没有延迟加载(应该预加载)。

您还可以使用AutoMapper将发布的视图模型映射回post方法中的Document实例,如下所示:

将反向映射添加到应用程序启动:

AutoMapper.Mapper.CreateMap<DocumentViewModel, Document>();

在控制器中:

[HttpPost]
public ActionResult Edit(DocumentViewModel viewModel)
{
    var document = AutoMapper.Mapper.Map<DocumentViewModel, Document>(viewModel);
}

希望这有帮助。

编辑:回答你的问题。在自动映射到查看模型之前,您可以在Document实例上调用manualSetLocationStr()。