5

私は過去数日間、MVC アプリケーションに取り組んできました。これで、私はいくつかのドロップダウンリストを使用しており、私が行ったことが良い習慣であるかどうかを知りたい. データベースから取り込まれた約 5 ~ 6 個のドロップダウンがあります。ドロップダウンには ID と説明フィールドがあります。問題なくドロップダウンを埋めることができます。ただし、マスターテーブルをリストしているときは、パフォーマンスの問題が発生しているときです。

すべてのドロップダウンの選択は整数としてデータベースに保存されるため、BaseModel (HBM にマップされるクラス) にもフィールドがあります。データベースからすべてのレコードを一覧表示すると、予想どおり、レコードに整数が表示されます。今のところ性能に問題はありません。

選択した項目の説明を表示したかったので、ドロップダウン用のモデル クラスを作成し、モデル内にデータベースと通信して選択内容に基づいて説明を取得するメソッドを用意しました。問題は、これがページの読み込みを遅くしていることです。これをより速くロードするためにデザインを変更する必要があるかどうかを知りたかった. 以下は私が持っているコードです

MasterList1 テーブル (このテーブルでは州と郡は整数です) 州のドロップダウン (ID を持つすべての州を含むマスター テーブル) 郡のドロップダウン (ID を持つすべての郡を含むマスター テーブル)

Nhibernate の BaseModel クラス

MasterList1 州郡

モデル クラス

MasterList1モデルの状態モデル郡モデル

リポジトリ クラス MasterList1Repo StateRepo CountyRepo

マスターリスト1を見る

ビューでは、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

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

Lists または Single オブジェクトを使用してそれを行うことができます。

コントローラーでこのメソッドを呼び出し、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 に答える
2

コードだけではなく、全体像を見ることから始めます。

hibernate.cfg.xml ファイルでこの設定をオンにしていますか?

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

生成された SQL を見て、両方のキャッシュ レベルが機能しているかどうか、および生成された SQL が最適かどうかを確認する必要があります。マッピングは、一括読み込みまたは遅延読み込みの設定に基づいて、返された行ごとに多くのクエリを実行している可能性があります。データベースのインデックス作成に問題がある場合もあります。また、データベースでトレースを実行して、実際に選択されて返されるデータの量と、データベースがこれを行うのにかかる時間を確認することもできます。

于 2013-05-31T13:18:37.247 に答える
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 に答える