【问题标题】:Nullable filters in XRM where clauseXRM where 子句中的可空过滤器
【发布时间】:2013-03-21 11:04:55
【问题描述】:

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

哪里[条款限制]

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

支持字符串函数 Contains、StartsWith、EndsWith 和 Equals。

不断弹出的一个要求是当参数为空时,所有实体都应返回,否则按参数过滤。但我想不出一种不违反要求的方法来做到这一点上面,或者编写多个查询来处理它为空时的场景。

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

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
            ...
        } );            
}

【问题讨论】:

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


    【解决方案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
                ...
            } );   
    }
    

    【讨论】:

    • 问题是我现在除了类型过滤器之外还必须添加一个开始/结束日期过滤器。使用 if/else 语句将查询写出 4 次以处理额外的过滤器有点多
    • 实际上超过 3 次,因为我认为您需要每个组合
    • 我认为您在 return 语句中不需要括号。
    【解决方案2】:

    我已经回答了我自己的问题!有时你只是需要一个地方在你得到它之前发泄你的问题。

    诀窍是不使用 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,
                ...
            }  );       
    }
    

    【讨论】:

      【解决方案3】:

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

      我已将它用于我目前正在从事的 Dynamics CRM 项目中,并且它做得非常好。

      请参考下面的答案,这是我的想法:https://stackoverflow.com/a/5152946/344988

      【讨论】:

        猜你喜欢
        • 2016-07-02
        • 2019-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多