Запрос Nibernate через несколько таблиц
-
01-10-2019 - |
Вопрос
Я использую Nhibernate, и я пытаюсь выяснить, как написать запрос, что ищет все имена моих субъектов и перечисляет результаты. Как простой пример, у меня есть следующие объекты;
public class Cat {
public string name {get; set;}
}
public class Dog {
public string name {get; set;}
}
public class Owner {
public string firstname {get; set;}
public string lastname {get; set;}
}
В дальнейшем я хочу создать запрос, скажем, например, который и возвращает все владельцы домашних животных с именем, содержащим «Тед» или домашних животных с именем, содержащим «Тед».
Вот пример SQL, который я хочу выполнить:
SELECT TOP 10 d.*, c.*, o.* FROM owners AS o
INNER JOIN dogs AS d ON o.id = d.ownerId
INNER JOIN cats AS c ON o.id = c.ownerId
WHERE o.lastname like '%ted%'
OR o.firstname like '%ted%'
OR c.name like '%ted%'
OR d.name like '%ted%'
Когда я делаю это, используя такие критерии:
var criteria = session.CreateCriteria<Owner>()
.Add(
Restrictions.Disjunction()
.Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere))
.Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere))
)
.CreateCriteria("Dog").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere))
.CreateCriteria("Cat").Add(Restrictions.Like("Name", keyword, MatchMode.Anywhere));
return criteria.List<Owner>();
Следующий запрос генерируется:
SELECT TOP 10 d.*, c.*, o.* FROM owners AS o
INNER JOIN dogs AS d ON o.id = d.ownerId
INNER JOIN cats AS c ON o.id = c.ownerId
WHERE o.lastname like '%ted%'
OR o.firstname like '%ted%'
AND d.name like '%ted%'
AND c.name like '%ted%'
Как я могу настроить свой запрос, чтобы .Createcriteria («собака») и .Createcriteria («CAT») генерируют или вместо и?
Спасибо за вашу помощь.
Решение
Попробуйте это, это может работать.
var criteria = session.CreateCriteria<Owner>()
.CreateAlias("Dog", "d")
.CreateAlias("Cat", "c")
.Add(
Restrictions.Disjunction()
.Add(Restrictions.Like("FirstName", keyword, MatchMode.Anywhere))
.Add(Restrictions.Like("LastName", keyword, MatchMode.Anywhere))
.Add(Restrictions.Like("c.Name", keyword, MatchMode.Anywhere))
.Add(Restrictions.Like("d.Name", keyword, MatchMode.Anywhere))
);
Другие советы
Вам необходимо объединить два критерия, используя Expression.or (критерии1, критерии2)
Подробнее здесь: http://devlicio.us/blogs/derik_whetker/archive/2009/04/21/Creating-a-neveReve-statement-with-nibernate-us-the-criteria-convention.aspx.aspx.
Хм, я думаю, что это будет выглядеть так (заимствовано немного от кода BuggyDigger)
var criteria = session.CreateCriteria<Owner>()
.CreateAlias("Dog", "d")
.CreateAlias("Cat", "c")
.Add(Expression.Or(Expression.Like("c.Name", keyword, MatchMode.Anywhere)
, Expression.Like("d.Name", keyword, MatchMode.Anywhere))
);
Но я не заметил, что вы хотели или все. В этом случае добавляя эти критерии дизъюнкции, как показал Buggydger, вероятно, путь к работе.