1

我在 WCF 项目中使用 XRM(早期绑定)类型,因此我可以访问 CRM 模型并且可以使用 LINQ 查询。但是我遇到了这里描述的问题where,这是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
            ...
        } );            
}
4

3 回答 3

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
            ...
        } );   
}
于 2013-03-21T11:24:45.370 回答
1

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

为此,我在我目前正在进行的 Dynamics CRM 项目中使用了它,并且它做得很好。

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

于 2013-03-21T17:55:31.450 回答
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,
            ...
        }  );       
}
于 2013-03-21T11:52:35.673 回答