XRM where子句中的可空过滤器

时间:2013-03-21 11:04:55

标签: c# linq dynamics-crm-2011 dynamics-crm xrm

我在WCF项目中使用XRM(早期绑定)类型,因此我可以访问CRM模型并可以使用LINQ查询。但是我一直遇到a problem described here,这是特定于XRM LINQ的where子句的限制:

  

[子句限制]

     

子句的左侧必须是属性名称,右侧是   该条款必须是一个值。您不能将左侧设置为常量。都   条款的两边不能是常数。

     

支持String函数Contains,StartsWith,EndsWith和Equals。

当一个参数为null时,一个不断弹出的要求是,所有实体都应该返回,否则按参数过滤。但我想不出办法在不违反要求的情况下做到这一点上面,或写入多个查询以处理该方案为空时。

这是我的一个查询的示例,typeFilter == null这里的问题是我在LHS上使用了一个常量。在我的真实代码中有一个保护条款将typeFilter == null指向另一个查询,但我现在必须添加一个开始/结束日期过滤器(都可以为空)我无法表达我想要为每个nullables组合写一个查询。

private IQueryable<EventInfo> getAllEvents( DataContext context, EventType? typeFilter )
{
    return (
        from evt in context.new_eventSet
        where
        ( evt.statecode == new_eventState.Active ) &&
        ( typeFilter == null || evt.new_EventType.Value == (int) typeFilter.Value )
        select new EventInfo()
        {
            ID = evt.Id,
            EventType = (EventType) evt.new_EventType.Value
            ...
        } );            
}

3 个答案:

答案 0 :(得分:1)

怎么样:

if (typeFilter == null)
{
        return (
        from evt in context.new_eventSet
        where
        ( evt.statecode == new_eventState.Active )
               select new EventInfo()
        {
            ID = evt.Id,
            EventType = (EventType) evt.new_EventType.Value
            ...
        } );   
}
else
{
        return (
        from evt in context.new_eventSet
        where
        ( evt.statecode == new_eventState.Active ) &&
        evt.new_EventType.Value == (int) typeFilter.Value )
        select new EventInfo()
        {
            ID = evt.Id,
            EventType = (EventType) evt.new_EventType.Value
            ...
        } );   
}

答案 1 :(得分:1)

我已经回答了我自己的问题!有时你只需要一个地方来发泄你的问题。

诀窍是不使用LINQ语法:

private IQueryable<EventInfo> getAllEvents( DataContext context, EventType? typeFilter, DateTime? startDateFilter, DateTime? endDateFilter  )
{
    var result = context.new_eventSet
        // active records
        .Where( evt => evt.statecode == new_eventState.Active )             
        // is publish-able
        .Where( ..etc.. );

    if ( typeFilter != null )
    {
        // filter by type
        result = result.Where( evt => evt.new_EventType.Value == (int) typeFilter.Value );
    }

    if( startDateFilter != null)
    {
        // filter by startDate
        result = result.Where(evt => evt.new_StartDate > startDateFilter.Value);
    }

    if( endDateFilter != null)
    {
        // filter by endDate
        result = result.Where(evt => evt.new_StartDate < endDateFilter.Value);
    }

    return result.Select( evt => new EventInfo()
        {
            ID = evt.Id,
            EventType = (EventType) evt.new_EventType.Value,
            ...
        }  );       
}

答案 2 :(得分:1)

如果要使用Linq语法,可以使用LinqKit动态构造查询。

我已经将它用于我目前正在研究的Dynamics CRM项目,并且它可以很好地完成这项工作。

请参考以下答案,我得到了这个想法:https://stackoverflow.com/a/5152946/344988