쿼리와 NHibernate
-
10-07-2019 - |
문제
나는 새로운 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.
Malcolm
<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 성분에,당신은 당신의 레시피 96times.당신은 인정하지 않기 때문에,이 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));
}
다른 팁
모두 Stefan 및 Sathish 의 예 연결%자로 SQL.이것은필과 공개적으로 연결됩으로 제한이 있습니다.다음과 같(nhib2.0+)고 표현합니다.다음과 같(전 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>();