2009-05-13 3 views
2

У меня есть SQL-запрос, который мне нужно представлять с помощью API ICriteria от NHibernate.NHibernate - присоединение к подзапросу с использованием ICriteria

SELECT u.Id as Id, 
    u.Login as Login, 
    u.FirstName as FirstName, 
    u.LastName as LastName, 
    gm.UserGroupId_FK as UserGroupId, 
    inner.Data1, 
    inner.Data2, 
    inner.Data3 
    FROM dbo.User u inner join 
    dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK 
    left join 
    (
     SELECT 
     di.UserAnchorId_FK, 
     sum(di.Data1) as Data1, 
     sum(di.Data2) as Data2, 
     sum(di.Data3) as Data3 
     FROM 
     dbo.DailyInfo di 
     WHERE di.Date between '2009-04-01' and '2009-06-01' 
     GROUP BY di.UserAnchorId_FK 
    ) inner ON inner.UserAnchorId_FK = u.Id 
    WHERE gm.UserGroupId_FK = 195 

попытки до сих пор включила отображение «User» и классы «DailyInfo» (мои лица) и делает DailyInfo объект свойства объекта пользователя. Однако, как отобразить отношение внешнего ключа между ними до сих пор загадка, т.е.

<one-to-one></one-to-one> 

<one-to-many></one-to-many> 

<generator class="foreign"><param name="property">Id</param></generator> (!) 

Решения в Интернете, как правило, делать с подзапросов внутри ИНЕКЕ, однако мне нужно налево присоединиться на этот подзапрос вместо убедитесь, что значения NULL возвращены для строк, которые не присоединяются.

У меня такое ощущение, что я должен использовать критерий для внешнего запроса, а затем создать «join» с DetachedCriteria для представления подзапроса?

ответ

0

Что касается отображения отношения, это звучит, как у вас есть отношения один-ко-многим между Пользователем и DailyInfo:

<!-- User mapping --> 
<bag name="DailyInfos" inverse="true"> 
    <key column="UserAnchorId_FK" /> 
    <one-to-many class="Namespace.To.DailyInfo, Namespace" /> 
</bag> 

<!-- DailyInfo mapping --> 
<many-to-one name="User" column="UserAnchorId_FK" /> 

Что касается остальных, я не совсем уверен, что на данный момент. .. Похоже, у вас может быть много-ко-многим между User и Group через таблицу GroupMember, что может быть осложняющим фактором. Имейте в виду, что вы можете сделать .CreateCriteria("Association path", jointype) по критериям для создания подкритериев с указанным типом соединения. Возможно, поможет опубликование краткого изложения ваших отношений между классами и таблицами.

1

Такая же проблема я столкнулся и я не получил никакого solutions.So я сделал хак с перехватчиком

запросы Сформированы по критериям

SELECT u.Id as Id, 
u.Login as Login, 
u.FirstName as FirstName, 
u.LastName as LastName, 
gm.UserGroupId_FK as UserGroupId, 
inner.Data1, 
inner.Data2, 
inner.Data3 
FROM dbo.User u inner join 
dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK 
InnerJoin inner ON inner.UserAnchorId_FK = u.Id 
WHERE gm.UserGroupId_FK = 195 

Здесь InnerJoin фиктивной таблица, которая имеет 1-1 отношения с пользователем. Столбцов в InnerJoin являются возвращаемыми значениями из внутреннего соединения подзапроса

Критерии для пользователя и InnerJoin

DetachedCriteria forUser = DetachedCriteria.For<User>(); 
forUser.CreateCriteria("InnerJoin"); 

Теперь вы можете сделать перехватчик редактировать запрос

public interface CustomInterceptor : IInterceptor, EmptyInterceptor 
{  
SqlString IInterceptor.OnPrepareStatement(SqlString sql) 
{ 
    string query = sql.ToString(); 
    if (query.Contains("InnerJoin ")) 
    { 
     sql = sql.Replace("InnerJoin ", "(select [vals] form dbo.DailyInfo [where conditions])"); 
    } 
    return sql; 
} 
} 

для возвращаемых значений из нескольких таблиц в том числе подключенный дополнительный запрос, вы можете использовать NHibernate DTO И такой сеанс

CustomInterceptor custonInterceptor=new CustomInterceptor(); 

sessionFactory.OpenSession(custonInterceptor); 

И окончательный запрос будет похож на то, что именно вы хотите получить

Смежные вопросы