Querying with NHibernate

后端 未结 3 1602
迷失自我
迷失自我 2021-02-04 17:08

I am new to NHibernate and I am trying to learn how to query my data.

Below is the configuration xml. Only the recipe is shown.

I want to be able to query recipe

3条回答
  •  长发绾君心
    2021-02-04 17:30

    To build dynamic queries, I would use the criteria API. This makes the dynamic query much more stable, because you don't need string operations to build it up.

    ICriteria query = Session.CreateCriteria(typeof(Recipe), "r")
      .CreateCriteria("Ingredients", "i", JoinType.InnerJoin)
      .Add(
        Expression.Disjunction() // OR
          .Add(Expression.Like("i.IngredientName", "%pasta%"))
          .Add(Expression.Like("i.IngredientName", "%wine%"))
          .Add(Expression.Like("r.RecipeTitle", "%pasta%"))
          .Add(Expression.Like("r.RecipeTitle", "%wine%")));
    
    List result = query.List();
    

    Edit:

    For eager loading you could set the fetch-mode:

    ICriteria query = Session.CreateCriteria(typeof(Recipe), "r")
      .SetFetchMode("Images", FetchMode.Join)
      .SetFetchMode("Comments", FetchMode.Join)
      .SetFetchMode("Ingredients", FetchMode.Join)
    

    But I wouldn't do this because you get the results multiplied by the number of Images, Comments and Ingredients. So if you had 4 Images, 2 Comments and 12 Ingredients, you get your recipe 96 times. You don't recognize this, because NHibernate puts the things together again, but it generates traffic between the application and the database. So better let NHibernate load it with separate queries.


    One more edit to show dynamic query composition.

    // filter arguments, all are optional and should be omitted if null
    List keywords;
    TimeSpan? minCookingTime;
    TimeSpan? maxCookingTime;
    int? minRating;
    int? maxRating;
    
    ICriteria query = Session.CreateCriteria(typeof(Recipe), "r");
    
    if (keyword != null)
    {
      // optional join
      query.CreateCriteria("Ingredients", "i", JoinType.InnerJoin);
    
      // add keyword search on ingredientName and RecipeTitle
      var disjunction = Expression.Disjunction();
      foreach (string keyword in keywords)
      {
        string pattern = String.Format("%{0}%", keyword);
        disjunction
          .Add(Expression.Like("i.IngredientName", pattern))
          .Add(Expression.Like("r.RecipeTitle", pattern)); 
      }
      query.Add(disjunction)
    }
    
    if (minCookingTime != null)
    {
      query.Add(Expression.Ge(r.CookingTime, minCookingTime.Value));
    }
    if (maxCookingTime != null)
    {
      query.Add(Expression.Le(r.CookingTime, maxCookingTime.Value));
    }
    
    if (minRating != null)
    {
      query.Add(Expression.Ge(r.Rating, minRating.Value));
    }
    if (maxRating != null)
    {
      query.Add(Expression.Le(r.Rating, maxRating.Value));
    }
    

提交回复
热议问题