How to implement NHibernate with ASP.NET MVC 2

I have been working on an MVC application for the past few days. In this I use a couple of dropdownlists and wanted what I did to be good practice. I have about 5-6 drop-down menus that are pulled from the database. There drop-down lists have an identifier and description field. I can get dropdown menus with the problem. However, when I list the main table, there is a performance issue.

All drop-down lists are saved as integers in the database, so I have a field just like in BaseModel (a class that maps to HBM). When I list all the records from the database, I predict that I get an integer in the record. So far I have no performance issues.

I wanted to display a description for the selected item in order to create a model class for the drop-down lists and have a method in the model that will talk to the database and get a description based on the selection. The problem is that it slows down the page loading. I wanted to know if I need to make a design change so that it loads faster. Below is the code that I have

MasterList1 table (state and county are integers in this table) State Dropdown (main table with all states with identifier) ​​Drop-down list window (main table with all counties with identifier)

BaseModel Classes for Nhibernate

MasterList1 State County

Model class

MasterList1Model StateModel CountyModel

Storage Class MasterList1Repo StateRepo CountyRepo

View MasterList1

In the view, I call a string property in the BaseModel class. In the property, I make a call to the Model class, which in turn sends a Repo call to get the string. Here is the method in the Repo class.

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

I am not sure how to improve this. Any suggestions?

+4
source share
3 answers

Do you know ViewModel Approuch? This is the class that represents the view that needs to be shown. You can create a ViewModel class with the necessary queries and enter your views with this class, populate it with NHibernate and then show it for a sample:

 public class ApplicationTypeMasterViewModel { public int Id { get; set; } public string Name { get; set; } public string CityName { get; set; } public string StateName { get; set; } // other properties you need public ApplicationTypeMasterViewModel() { } } 

at your service level, try something like this:

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

You can do this using lists or individual objects.

In the controller, you call this method and pass the ViewModel to your view and render it:

 <p> <label>Name: </labe> <%: Model.Name %> </p> <p> <label>City: </labe> <%: Model.CityName %> </p> <p> <label>State: </labe> <%: Model.StateName %> </p> 
+2
source

I would start by looking at the big picture, not just the code.

Do you have this option enabled in the hibernate.cfg.xml file?

<property name = "show_sql"> true </property>

You should look at the generated SQL to see if both levels of the cache work, and if your generated SQL is optimal. Your mapping can do many queries for each returned string based on your desired or lazy load settings. You might even have a problem with indexing in your database. You can also run a trace in the database and see how much data is actually fetched and returned, and how long the database has been taking this.

+2
source

In general, reading performance can be a problem when using ORM. If lazy loading does not work for you (you must first find out), another way to mitigate the problem is to use a custom query for certain read operations that are not efficient. You can use NHibernate for this if you want.

Here is an example of a method in the repository that executes a user request and returns a DTO (HostingItem in this example) using 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 will create a list of DTOs for you, you do not need any mappings or anything else for this.

+1
source

Source: https://habr.com/ru/post/1482338/


All Articles