سؤال

أنا جديدة على NHibernate وأنا في محاولة لمعرفة كيفية الاستعلام البيانات الخاصة بي.

أدناه هو التكوين xml.فقط وصفة مبين.

كنت تريد أن تكون قادرة على الاستعلام وصفات recipetitle من كلمات دخلت وأيضا المكونات من ingredientname.

لذلك قد أدخل "المعكرونة النبيذ" على سبيل المثال.

هذا ما حاولت ولكن يعطيني خطأ.

    hql = "from Recipe r " +
    "left join r.Images " +
    "inner join r.User " +
    "inner join r.Ingredients i " +
    "where i.IngredientName Like '%pasta%' OR i.IngredientName Like '%wine%' OR r.RecipeTitle Like '%pasta' OR r.RecipeTitle Like '%wine%'";

أريد حريصة تحميل مجموعات أيضا.

أنا ذاهب عن الاستعلام أليس كذلك ؟ ؟ أنا بحاجة إلى قادرا على بناء سلسلة الاستعلام من معايير البحث.هذا سيكون من السهل شكل لي في SQL.

مالكوم

  <class name="Recipe" table="Recipes" xmlns="urn:nhibernate-mapping-2.2">
    <id name="RecipeID" type="Int32" column="RecipeID">
      <generator class="identity" />
    </id>
    <property name="RecipeTitle" type="String">
      <column name="RecipeTitle" />
    </property>
    <property name="Completed" type="Boolean">
      <column name="Completed" />
    </property>
    <property name="ModifiedOn" type="DateTime">
      <column name="ModifiedOn" />
    </property>
    <property name="Rating" type="Double">
      <column name="Rating" />
    </property>
    <property name="PrepTime" type="Int32">
      <column name="PrepTime" />
    </property>
    <property name="CookTime" type="Int32">
      <column name="CookTime" />
    </property>
    <property name="Method" type="String">
      <column name="Method" />
    </property>
    <bag name="Images" inverse="true" cascade="all">
      <key column="RecipeID" />
      <one-to-many class="OurRecipes.Domain.RecipeImage, OurRecipes.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <many-to-one name="Category" column="CategoryID" />
    <bag name="Comments" inverse="true" cascade="all">
      <key column="RecipeID" />
      <one-to-many class="OurRecipes.Domain.Comment, OurRecipes.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <many-to-one name="User" column="EnteredByID" />
    <bag name="Ingredients" inverse="true" cascade="all">
      <key column="RecipeID" />
      <one-to-many class="OurRecipes.Domain.Ingredient, OurRecipes.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
هل كانت مفيدة؟

المحلول

لبناء ديناميكية الاستعلامات, وأود أن استخدام معايير API.هذا يجعل ديناميكية الاستعلام أكثر استقرارا ، لأنك لا تحتاج إلى سلسلة من عمليات بناء ما يصل.

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<Recipe> result = query.List<Recipe>();

تحرير:

بالنسبة حريصة التحميل بإمكانك ضبط الجلب-الوضعية:

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

ولكن أنا لن أفعل هذا لأنه يمكنك الحصول على نتائج مضروبة في عدد من الصور والتعليقات المكونات.حتى إذا كان لديك 4 صور 2 تعليقات و 12 المكونات ، يمكنك الحصول على وصفة 96 مرات.كنت لا أعرف هذا لأن NHibernate يضع الأشياء معا مرة أخرى ، ولكنه يولد حركة المرور بين التطبيق وقاعدة البيانات.لذلك من الافضل ترك NHibernate تحميل منفصلة مع الاستعلامات.


أحد أكثر تحرير عرض ديناميكية استعلام تكوين.

// filter arguments, all are optional and should be omitted if null
List<string> 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));
}

نصائح أخرى

وكل من ستيفان والأمثلة ساثيش في سلسلة مشغلي٪ في SQL. هذا هو unnecesary كما Restrictions.Like (nhib 2.0+) وExpression.Like (قبل V2.0) لديها 3 إصدارات المعلمة مع MatchMode.

Disjunction keywordsCriteria = Restrictions.Disjunction();
foreach (var keyword in keywords)
{
    keywordsCriteria.Add(Restrictions.Like("i.IngredientName", keyword, MatchMode.Anywhere));
    keywordsCriteria.Add(Restrictions.Like("r.RecipeTitle", keyword, MatchMode.Anywhere));
}

والاستفسارات النص الكامل تتوفر مع NHibernate البحث أيضا. انظر Ayende في المثال للحصول على مزيد من التفاصيل.

وهنا هي المعايير المذكورة أعلاه مع كلمات ديناميكية

string searchQuery = "wine pasta";

ICriteria query = Session.CreateCriteria(typeof(Recipe), "r")
                    .CreateCriteria("Ingredients", "i", JoinType.InnerJoin)
                    .SetFetchMode("Images", FetchMode.Join)
                    .SetFetchMode("Comments", FetchMode.Join)
                    .SetFetchMode("Ingredients", FetchMode.Join)
                    .SetResultTransformer(new DistinctRootEntityResultTransformer());

var keywords = searchQuery.Split(' ');

Disjunction keywordsCriteria = Restrictions.Disjunction();
foreach (var keyword in keywords)
{
    keywordsCriteria.Add(Restrictions.Like("i.IngredientName", string.Format("%{0}%", keyword)));
    keywordsCriteria.Add(Restrictions.Like("r.RecipeTitle", string.Format("%{0}%", keyword)));
}

query.Add(keywordsCriteria);

List<Recipe> result = query.List<Recipe>();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top