1

WCFプロジェクトでXRM(アーリーバウンド)タイプを使用しているので、CRMモデルにアクセスでき、LINQクエリを使用できます。しかし、ここで説明する問題が発生whereしました。これは、 XRMLINQに固有の句の制限です。

ここで[条項の制限]

句の左側は属性名である必要があり、句の右側は値である必要があります。左側を定数に設定することはできません。句の両側を定数にすることはできません。

文字列関数Contains、StartsWith、EndsWith、およびEqualsをサポートします。

ポップアップし続ける要件の1つは、パラメーターがnullの場合、すべてのエンティティを返す必要があります。それ以外の場合は、パラメーターでフィルター処理します。しかし、上記の要件を破ったり、シナリオがnullの場合にシナリオを処理するために複数のクエリを記述したりせずに、これを行う方法を考えることはできません。

これは私のクエリの1つの例です。typeFilter == nullここでの問題は、LHSで定数を使用したことです。私の実際のコードには、別のクエリを指すガード句がありtypeFilter == nullますが、開始/終了日フィルター(両方ともnull許容)を追加する必要があり、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 に答える