0

会社のアプリケーションで一種の「ニュースフィード」を作りたいです。シナリオでは、ユーザーアクションはさまざまな種類の「アクティビティ」を生成し、他のユーザーは「ニュースフィード」に表示されます。

ただし、「アクティビティ」はすべてのユーザーに関連しているわけではなく、関係を判断するために、複雑なコードがあります。

これが私のアクティビティクラスです

public class Activity: IActivity
{
    public virtual int Id { get; set; }
    public virtual ActivityType Type { get; set; }
    public virtual User User { get; set; }
    public virtual bool IsVisibleToUser(User userLook)
    {
        // Complex business calculation etc.
        return true;
    }
}

ユーザーに表示される最新の10のニュースを取得したい。ただし、アクティビティテーブルは非常に大きくなり、パフォーマンスが問題になるため、ベストプラクティスを実行したいと思います。

私がやろうとしていることは、最後の25のアクティビティを取得し、ユーザーに表示するリストを埋めるかどうかを確認することです。たとえば、ユーザーに表示されるアクティビティが5つだけの場合、さらに25のアクティビティを取得します。

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .SetMaxResults(25)
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

リスト全体をId順に並べて、ユーザーに表示されているかどうかを1つずつ確認した場合、NHibernateは使用するオブジェクトのみをロードするかどうかを知りたいですか?

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

int count = 0;
foreach( Activity act in resultList){
    if (act.IsVisible(CurrentUser)){
        count++;
        // Do something with act
        if (count == 10)
            break;
    }
}

編集:これがアクティビティモデルのActivityMappingです。

public class ActivityMap : ClassMap<Activity>
{
    public ActivityMap()
    {
        Id(x => x.Id);
        Map(x => x.Type).CustomType(typeof(Int32));
        References(x => x.User).Nullable();
    }
}
4

2 に答える 2

3

生成されたSQLがどのように見えるかについての質問の場合、私の推測は次のようになります。

SELECT 
   this_.Id as Id0_0_, 
   this_.ActivityTypeas ActivityType_0_0_, 
   --Other fields
FROM dbo.ActivityType this_ 
WHERE 
   --condition
ORDER BY 
   --condition

アクティビティ数が多いとおっしゃっていたので、ICriteriaSetFirstResultとを利用できますSetMaxResult

SetFirstResult(int)取得したい最初のアイテムのインデックスをSetMaxResult(int)示し、取得したい行数を示します。この場合は25行です。

ToList、メモリ内のすべてのレコードを一度にロードします。

[更新]レコードを1つずつ返す必要がある場合は、Enumerable()を使用してください-

クエリが非常に多くのオブジェクトを返すことを期待しているが、それらすべてを使用することを期待していない場合は、System.Collections.IEnumerableを返すEnumerable()メソッドのパフォーマンスが向上する可能性があります。イテレータは、最初のSQLクエリによって返された識別子を使用してオブジェクトをオンデマンドでロードします(n + 1は合計を選択します)。

ソース-リンク

于 2011-03-31T18:09:44.067 に答える
2

いいえ、List()メソッドはすべてを一度にメモリにプルします。

于 2011-03-31T18:09:50.357 に答える