1

NHibernate を使用してこのクエリを作成しました。

public IList<Category> GetCategoriesByUsername(string username)
{
    Category cAlias = null;
    User uAlias = null;
    Keyword kAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .JoinAlias(() => cAlias.User, () => uAlias)
    .Where(() => uAlias.Username == username)
    .Future<Category>();

    var keywords = SessionFactory.GetCurrentSession().QueryOver<Keyword>(() => kAlias)
    .JoinAlias(c => c.Category, () => cAlias)
    .Where(() => cAlias.Id == kAlias.Category.Id)
    .Future<Keyword>();

    IList<Category> list = (List<Category>)categories.ToList();

    return list;
}

これは問題なく機能し、各カテゴリに独自のキーワードがあるカテゴリのリストが表示されます。私のサービスレイヤーでは、Automapper を使用して ViewModel に変換しようとしていますが、期待どおりには機能しません。カテゴリ リスト内のキーワードごとに、新しいクエリ (N+1) が作成されます。リスト内の各カテゴリに既に入力されているキーワードは使用されません。

これらは私のモデルとビューモデルです:

public class Category
{
    public virtual Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Keyword> Keywords { get; set; }
    public virtual User User { get; set; }
}

public class CategoryView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<KeywordSummaryView> Keywords { get; set; }
}

public class Keyword
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual Category Category { get; set; }
}

public class KeywordSummaryView
{
    public int Id { get; set; }
    public string Name { get; set; }
}

私のマッピング:

public class AutoMapperBootStrapper
{
    public static void ConfigureAutoMapper()
    {
        Mapper.CreateMap<Category, CategoryView>();
        Mapper.CreateMap<Keyword, KeywordSummaryView>();
    }
}

public static class CategoryMap
{
    public static IList<CategoryView> ConvertToCategoryView(this IList<Category> category)
    {
        return Mapper.Map<IList<Category>, IList<CategoryView>>(category);
    }
}

モデルからViewModelへ:

IList<Category> categories = _categoryRepository.GetCategoriesByUsername(request.Username);

response.Categories = categories.ConvertToCategoryView();

リスト内の各カテゴリに既に入力されているキーワードを使用するのではなく、各キーワード (N+1) に対して新しいクエリを作成します。私が間違っていることはありますか?

4

1 に答える 1

1

これらの両方がN + 1選択を防ぐはずだと思います

public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .Fetch(x => x.Keywords ).Eager
    .JoinAlias(() => cAlias.User, () => uAlias)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories ;
}


public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;
    Keyword kAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .JoinAlias(() => cAlias.User, () => uAlias)
    .JoinAlias(x => x.Keywords , () => kAlias, JoinType.LeftOuterJoin)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories;
}

これが役立つことを願っています

于 2013-02-27T14:31:10.737 に答える