在nhibernate 3.3.1.4000中没有明确关系的左连接

时间:2012-10-17 12:05:54

标签: linq nhibernate

我有两个简化的实体:

public class Measurement : Entity
{
    public virtual float DisplayValue { get; set; }
    private DateTime _timeStamp;
    public virtual DateTime TimeStamp
    {
        get { return _timeStamp; }
        set { _timeStamp = value.ToUniversalTime(); }
    }
}

public class TimeStamp : Entity
{
    public virtual DateTime TimeStampEntry { get; set; }
}

我正在使用这个(我的)sql代码来确定范围内的缺失值:

SET time_zone='+0:00';  
select 
    a.TimeStampEntry,
    b.DisplayValue
from timestamps as a 
left outer join  
(
    select
        TimeStamp,
        DisplayValue
    from measurements 
) as b on a.TimeStampEntry = b.TimeStamp
where a.TimeStampEntry>='2010-01-01 00:00:00' and a.TimeStampEntry<'2010-01-31 23:59:59' and b.DisplayValue is null
order by a.TimeStampEntry asc

我只是想知道如何在Nhibernate 3.x中实现这一点,最好是在Linq中。

顺便说一下,我没有尝试过任何严肃的事情,因为日期时间字段之间的关系没有在流利的nhibernate中定义。不确定我是否必须定义它才能使用ICriteria,Linq,HQL或其他任何东西。任何反馈都将非常感激。感谢。

PS:

我已经开始这个(不是工作代码):

var x = (from ts in NHibernateSession.Current.Query<TimeStamp>()
                         join m in NHibernateSession.Current.Query<Measurement>()
                         on ts.TimeStampEntry equals m.TimeStamp into ps
                         from m in ps.DefaultIfEmpty()
                         select new { m.TimeStamp }).ToList();

PPS:

堆栈跟踪:

at NHibernate.Linq.Visitors.QueryModelVisitor.VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, Int32 index)
   at Remotion.Linq.Clauses.GroupJoinClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
   at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
   at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
   at Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

1 个答案:

答案 0 :(得分:0)

看起来你真的不需要左连接 - 你只是在聚合中使用正确的表。这是一个更简单(在LINQ中)组连接的好地方:

DateTime start = DateTime.new(year, month, 1);
DateTime end = start.AddMonths(1);

var x =
    from ts in NHibernateSession.Current.Query<TimeStamp>()
    join m in NHibernateSession.Current.Query<Measurement>()
        on ts.TimeStampEntry equals m.TimeStamp
        into ps
    where
        ts.TimeStampEntry >= start &&
        ts.TimeStampEntry < end &&
        ! ps.Any()
    orderby ts.TimeStampEntry
    select ts.TimeStampEntry;