2013-03-21 2 views
1

Я использую типы XRM (ранней привязки) в проекте WCF, поэтому у меня есть доступ к модели CRM и я могу использовать запросы LINQ. Но я бег в a problem described here, это ограничение на пункте where специфичное для XRM LINQ:Nullable filters in XRM where where

где [оговорка ограничения]

Левая сторона пункта должна быть именем атрибута и правая сторона должно быть значением. Вы не можете установить левую сторону в константу. Как стороны предложения не могут быть константами.

Поддерживает функции String Содержит, запускает с, имеет значение EndsWith и Equals.

Одно требование, которое продолжает выскакивать, - это , когда параметр имеет значение null, все объекты должны быть возвращены в противном случае фильтром по параметру. Но я не могу придумать способ сделать это, не нарушая вышеприведенных требований, или писать несколько запросов для обработки сценария, когда он равен нулю.

это пример одного из моих запросов, проблема 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 
      ... 
     });    
} 

ответ

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

проблема в настоящее время я должен добавить фильтр даты начала/окончания в дополнение к типу фильтра. записывая запрос 4 раза с помощью if/else для обработки дополнительных фильтров, немного больше –

+0

фактически более 3 раз, так как я думаю, что вам понадобится каждая комбинация –

+0

Я не думаю, что вам нужны скобки в * return * заявление. –

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

Если вы хотите использовать синтаксис Linq, можно построить запрос динамически с помощью LinqKit.

Я использовал его для этой цели в проекте Dynamics CRM, над которым я сейчас работаю, и он отлично справляется с этой задачей.

Пожалуйста, обратитесь к следующему ответу, который где я получил идею: https://stackoverflow.com/a/5152946/344988