5

过去几天我一直在研究 MVC 应用程序。在此,我使用了几个下拉列表,并希望我所做的是否是一个好习惯。我从数据库中提取了大约 5-6 个下拉列表。下拉菜单有一个 ID 和描述字段。我能够毫无问题地填写下拉列表。但是,当我列出主表时,我遇到了性能问题。

所有下拉选择都以整数形式存储在数据库中,因此我也拥有 BaseModel 中的字段(映射到 HBM 的类)。当我列出数据库中的所有记录时,可以预见的是,我会在记录中得到一个整数。到目前为止,我的性能没有问题。

我想显示所选项目的描述,因此我为下拉菜单创建了一个模型类,并在模型中有一个方法,该方法将与数据库对话并根据选择获取描述。问题是这会减慢页面加载速度。我想知道我是否需要进行设计更改以更快地加载它。以下是我的代码

MasterList1 表(州和县在此表中是整数) State Dropdown(主表具有所有具有 ID 的州) County Dropdown(主表具有所有具有 ID 的县)

Nhibernate 的 BaseModel 类

MasterList1州县

模型类

MasterList1Model StateModel CountyModel

Repository Class MasterList1Repo StateRepo CountyRepo

查看 MasterList1

在视图中,我在 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();
    }

我不确定如何改善这一点。有什么建议么 ?

4

3 回答 3

2

我会从大局开始,而不仅仅是代码。

您是否在 hibernate.cfg.xml 文件中打开了此设置?

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

您应该查看生成的 SQL 以查看两个缓存级别是否正常工作以及生成的 SQL 是否是最佳的。您的映射可能会根据您的急切或延迟加载设置对每个返回的行执行许多查询。您甚至可能在数据库中遇到索引问题。您可能还想在数据库上运行跟踪并查看实际选择和返回的数据量以及数据库执行此操作所需的时间。

于 2013-05-31T13:18:37.247 回答
2

你知道ViewModel方法吗?它是一个类,表示视图需要显示的内容。您可以使用您需要的这些属性创建一个 ViewModel 类,并使用该类键入您的视图,用 NHibernate 填充它,然后显示它,例如:

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

在您的服务层,尝试这样的事情:

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 传递给您的 View 并渲染它:

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

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


<p>
    <label>State: </labe>
    <%: Model.StateName %>
</p>
于 2013-05-28T15:14:27.810 回答
1

通常,使用 ORM 时,读取操作的性能可能会成为问题。如果延迟加载对您不起作用(您应该首先进行调查),缓解问题的另一种方法是对不具有性能的特定读取操作使用自定义查询。如果你愿意,你可以使用 NHibernate。

下面是在 NHibernate 的帮助下执行自定义查询并返回 DTO(本示例中为 HostingItem)的存储库上的方法示例:

        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 列表,您不需要任何映射或任何东西。

于 2013-05-31T14:08:08.600 回答