Access to field of child class from base class
I don't know is it possible to do. I have two classes:
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
}
}
}
And here second class:
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;
}
}
}
So my question is how can I call manualSetLocationStr()
in contructor of Document? I need this to avoid second retrieving information from DB in locationStr
get accessor, 'cause I already have it (this is field3
in Document contructor).
Any advice, any thoughs will be very appreciated.
Strongly hope for your help!
Thanks in advance!
Why can't the field3
value be stored as a property of Document
? Also, it is more standard for view models to contain an instance of their model, rather than derive from them.
Update
It depends on your architecture, but you could create a DocumentInfo
type for example which has all of the properties required for your view. Then you need to populate a collection of these for your view, you can use a DocumentInfoRepository
which provides the abstraction over the data access. This repository can either be accessed directly in your entity or from your controller, depending on the type of your domain model and the patterns you wish to employ.
Seeing how you have OracleConnection property on a view model class - it just seems wrong. Assuming you have created the DocumentViewModel class I would strongly urge you to populate it in the controller and omit OracleCOnnection from it. Instead of inheriting from Document you can use AutoMapper to map it instead. This involves 2 simple steps:
You do this once per application start:
AutoMapper.Mapper.CreateMap<Document, DocumentViewModel>();
And then use it in controller:
var viewModel = AutoMapper.Mapper.Map<Document, DocumentViewModel>(documentInstance);
This will create an instance of DocumentViewModel and map as many properties as it can. By doing this you get around the need to inherit from your Document class.
As for the structure of your view model. Instead of having a method typeStr, have a property TypeStr which is set after auto mapping in controller action. Same goes for your typeStr method.
The whole idea of view models is to provide UI with a dumb as possible representation of data to render. So ideally no method calls, no lazy loading (should be preloaded).
You can also use the AutoMapper to map your posted view model back to Document instance in post method, like so:
Add reverse mapping to application start:
AutoMapper.Mapper.CreateMap<DocumentViewModel, Document>();
And in controller:
[HttpPost]
public ActionResult Edit(DocumentViewModel viewModel)
{
var document = AutoMapper.Mapper.Map<DocumentViewModel, Document>(viewModel);
}
Hope this helps.
EDIT: To answer your question. You would call manualSetLocationStr() on the Document instance prior to auto mapping to view model.
精彩评论