2013-05-23 1 views
4

Я работаю над приложением MVC в течение последних нескольких дней. В этом я использую пару dropdownlists и хотел, чтобы то, что я сделал, является хорошей практикой. У меня около 5-6 выпадающих меню, которые вытаскиваются из базы данных. Там выпадающие списки имеют поле идентификатора и описания. Я могу получить выпадающие меню с проблемой. Однако, когда я перечисляю главную таблицу, у меня возникает проблема с производительностью.КАК ПОЯВИТЬ НА NHibernate с ASP.NET MVC 2

Все выпадающие списки сохраняются как целочисленные в базе данных, поэтому у меня есть поле также как в BaseModel (класс, который отображается на HBM). Когда я перечисляю все записи из базы данных, я предсказую, что получаю целое число в записи. Пока у меня нет проблем в производительности.

Я хотел показать описание для выбранного элемента, чтобы создать класс модели для выпадающих списков и иметь метод в модели, который будет разговаривать с базой данных и получать описание на основе выбора. Проблема в том, что это замедляет загрузку страницы. Я хотел знать, нужно ли мне сделать изменение дизайна, чтобы оно было загружено быстрее. Ниже приведен код, который я

MasterList1 Table (Государство и округа являются целыми числами в этой таблице) раскрытом состоянии (Master стол, имеющий все состояния с ID) County Dropdown (Мастер таблицу, имеющую все уезды с ID)

BaseModel Классы для NHibernate

MasterList1 государственного округа

Модель класса

MasterList1Model StateModel CountyModel

Repository Класс MasterList1Repo StateRepo CountyRepo

Посмотреть MasterList1

В представлении я звоню строку proprty в классе BaseModel. В свойстве я делаю вызов класса Model, который, в свою очередь, отправляет вызов Repo для получения строки. Вот метод в классе Repo.

 public ApplicationTypeMaster GetByID(int ID) 
    { 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      return session.Get<ApplicationTypeMaster>(ID); 
     } 
    } 

    public string GetApplicationTypeByID(int ID) 
    { 
     return GetByID(ID).ApplicationTypeDescription.ToString(); 
    } 

Я не уверен, как улучшить это. Какие-либо предложения ?

+0

Не могли бы вы добавить свой код? –

+0

View имеет model => model.ApplicationTypeDescription rendered. Это свойство вызывает вызов класса Model, который запрашивает коллекцию, которую я загружаю при загрузке страницы. Это то, что вы искали @jeroenk? – vikramjb

+0

Это действительно сложно сказать, ваш пример недостаточно ясен. Если бы вы могли создать образец приложения и поделиться им с sharebox, который будет оценен. Одна рекомендация, которую я могу сделать, - это изучить кэширование 2-го уровня NHibernates, чтобы уменьшить количество запросов к базе данных. Вы также можете подумать о создании своего собственного статического кеша в памяти этих объектов, если они не меняются со временем. Может предоставить вам несколько конкретных примеров, если вы предоставите более подробное описание для нас. – ctrlplusb

ответ

2

Знаете ли вы, что ViewModel подходят? Это класс, который представляет собой представление, которое нужно показать. Вы можете создать класс ViewModel с тезисами proeprties вам нужно, и введите ваши взгляды с этим классом, заполнить его с NHibernate, а затем показать, для образца:

public class ApplicationTypeMasterViewModel 
{ 
    public int Id { get; set; } 
    pubic string Name { get; set; } 
    pubic string CityName { get; set; } 
    pubic string StateName { get; set; } 

    // other properties you need 

    public ApplicationTypeMasterViewModel() { } 
} 

в вашей службе слоя, попробовать что-то вроде этого:

public ApplicationTypeMasterViewModel GetByID(int ID) 
    { 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      return session.Query<ApplicationTypeMaster>() 
                .Fetch(x => x.City).ThenFetch(c => c.State) 
          .Where(x => x.Id == ID) 
          .Select(x => new ApplicationTypeMasterViewModel() { 
                Id = x.Id, 
                Name = x.Name, 
                CityName = x.City.Name, 
                StateName = x.City.State.Name 
                // other properties you need 
              }) 
          .FirstOrDefault(); 
     } 
    } 

Вы можете сделать это, используя списки или отдельные объекты.

В контроллере вы вызываете этот метод и передать ViewModel на ваш взгляд и сделать его:

<p> 
    <label>Name: </labe> 
    <%: Model.Name %> 
</p> 

<p> 
    <label>City: </labe> 
    <%: Model.CityName %> 
</p> 


<p> 
    <label>State: </labe> 
    <%: Model.StateName %> 
</p> 
+0

Да, я знаю подход ViewModel. Однако я не реализовал его, потому что он купил бы дополнительный слой для текущей реализации. Суть проблемы в том, что я пытаюсь перечислить 100 записей, которые имеют 5 таких просмотров. Это займет 25 секунд, чтобы перечислить их. Я подозреваю, что это из-за непрерывных вызовов базы данных каждый раз, когда он пытается получить описание. Чтобы улучшить это, я загрузил все основные значения в ICollection и запросил коллекцию, когда я делаю список. Время загрузки составляет 20 секунд. Не знаю, как я могу улучшить его производительность. – vikramjb

+0

Возможно, он выполняется lazyLoading, вы можете попробовать использовать EargLoading с использованием методов расширения Fetch, FetchMany для Nhibernate To Linq и использовать его для выполнения одного запроса в базе данных. Смотрите мои правки –

2

Я хотел бы начать, глядя на картину, а не только в коде.

У вас есть эта настройка включена в файле hibernate.cfg.xml?

< имя свойства = " show_sql " > истинный </недвижимость >

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

1

В целом, при использовании ORM проблема с производительностью при чтении может быть проблемой. Если для вас не работает ленивая загрузка (сначала вы должны это выяснить), еще один способ смягчить проблему - использовать пользовательский запрос для определенных операций чтения, которые не являются результативными. Вы можете использовать NHibernate для этого, если хотите.

Вот пример метода на хранилище, которое выполняет пользовательский запрос и возвращает DTO (HostingItem в данном примере) с помощью NHibernate:

 public IList<HostingItem> GetHostingItems() 
     { 
      const string query = @" 
       select 
        c.id, 
        c.name as CustomerName, 
        p.name as ProductName, 
        wl.DomainName 
       from 
        WorkOrderLines wl 
       inner join 
        WorkOrders w on w.id = wl.workorder_id 
       inner join 
        Customers c on c.id = w.customer_id 
       inner join 
        Products p on p.id = wl.product_id 
       where 
        wl.active = 1 and 
        wl.type = 'HostingProductWorkOrderLine' and 
        parent_id is null and 
        wl.invoice_id is not null"; 

      return Session.CreateSQLQuery(query) 
       .AddScalar("Id", NHibernateUtil.Int32) 
       .AddScalar("CustomerName", NHibernateUtil.String) 
       .AddScalar("ProductName", NHibernateUtil.String) 
       .AddScalar("DomainName", NHibernateUtil.String) 
       .SetResultTransformer(Transformers.AliasToBean(typeof (HostingItem))) 
       .List<HostingItem>(); 
     } 

    public class HostingItem 
    { 
     public int Id { get; set; } 
     public string CustomerName { get; set; } 
     public string DomainName { get; set; } 
     public string ProductName { get; set; } 
    } 

NHibernate создаст список DTO для вам, вам не нужны какие-либо сопоставления или что-то еще для этого.