Доступ к полю дочернего класса из базового класса - PullRequest
0 голосов
/ 13 июля 2011

Я не знаю, возможно ли это сделать. У меня есть два класса:

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;
                } 
            }    
        }

Итак, мой вопрос: как мне вызвать manualSetLocationStr() в конструкторе Document? Мне нужно это, чтобы избежать повторного получения информации из БД в locationStr get accessor, потому что она у меня уже есть (это field3 в Document contructor). Любые советы, любые мысли будут очень цениться. Сильно надеюсь на вашу помощь! Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 13 июля 2011

Почему значение field3 не может быть сохранено как свойство Document?Кроме того, для моделей представления более стандартно содержать экземпляр своей модели, а не наследовать от них.

Обновление

Это зависит от вашей архитектуры, но выможет создать тип DocumentInfo, например, который имеет все свойства, необходимые для вашего представления.Затем вам нужно заполнить их коллекцию для просмотра, вы можете использовать DocumentInfoRepository, который обеспечивает абстракцию доступа к данным.Доступ к этому хранилищу может быть либо непосредственно в вашей сущности, либо с вашего контроллера, в зависимости от типа модели вашего домена и шаблонов, которые вы хотите использовать.

0 голосов
/ 13 июля 2011

Видеть, как у вас есть свойство OracleConnection в классе модели представления - это просто кажется неправильным. Предполагая, что вы создали класс DocumentViewModel, я настоятельно рекомендую вам заполнить его в контроллере и исключить из него OracleCOnnection. Вместо того, чтобы наследовать от Document, вы можете использовать AutoMapper для сопоставления. Это включает в себя 2 простых шага:

Вы делаете это один раз за запуск приложения:

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

А затем используйте его в контроллере:

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

Это создаст экземпляр DocumentViewModel и отобразит как можно больше свойств. Делая это, вы избавляетесь от необходимости наследовать от вашего класса Document.

Что касается структуры вашей модели представления. Вместо того, чтобы иметь метод typeStr, имейте свойство TypeStr, которое устанавливается после автоматического сопоставления в действии контроллера. То же самое относится и к вашему методу typeStr.

Вся идея моделей представлений состоит в том, чтобы предоставить пользовательскому интерфейсу тупое максимально возможное представление данных для визуализации. Так что в идеале не нужно вызывать методы и загружать ленивый (должен быть предварительно загружен).

Вы также можете использовать AutoMapper, чтобы отобразить вашу опубликованную модель представления обратно в экземпляр Document в методе post, например так:

Добавить обратное отображение к запуску приложения:

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

А в контроллере:

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

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос. Вы бы вызвали manualSetLocationStr () для экземпляра Document перед автоматическим сопоставлением для просмотра модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...