vb.net iif условие в запросе linq где предложение - PullRequest
2 голосов
/ 25 августа 2011

Что не так с приведенным ниже запросом, я получаю эту ошибку: Обнуляемый объект должен иметь значение.

  Dim subscriptionUsers = From inv In dataContext.Invoices.ToList Join u In dataContext.Users _
                                    On inv.Subscription Equals u.Subscription _
                                    Where inv.Id.Value = invoiceID _
                                    And Not u.Fund.Title.Contains("AGM") _
                                    And DirectCast(IIf(Not u.EndDate.HasValue, IIf(u.StartDate.Value <= inv.EndDate.Value, True, False), _
                                                    IIf((u.StartDate.Value >= inv.StartDate.Value And u.StartDate.Value <= inv.EndDate.Value) Or _
                                                (u.EndDate.Value >= inv.StartDate.Value And u.EndDate.Value <= inv.EndDate.Value) Or _
                                                (u.StartDate.Value < inv.StartDate.Value And u.EndDate.Value > inv.EndDate.Value), True, False)), Boolean) _
                                Group By Key = u.Fund.Title Into Group _
                                Select Fund = Key, UsersCount = Group.Count, Users = Group.ToList, _
                                SubFunds = (From a In dataContext.Allocations Where a.Fund.Title = Key Select a.Department.Title Distinct)

Если я удаляю u.EndDate.Value в условии, тогда он работает нормально.

Вот трассировка стека:

в System.Nullable 1.get_Value() at SDBReports.InvoiceAllocationReportUserControl._Lambda$__4(VB$AnonymousType_0 2 $ VB $ It) в System.Linq.Enumerable.WhereEnumerableIterator 1.MoveNext() at System.Linq.Lookup 2.Create [TSource] (IEnumerable 1 source, Func 2 keySelector, Func 2 elementSelector, IEqualityComparer 1 компаратор) at System.Linq.GroupedEnumerable 4.GetEnumerator() at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext () at System.Linq.SystemCore_EnumerableDebugView`1.get_Items ()

p.s. Я использовал SPMetal для создания классов сущностей в списках SharePoint.

Для большей ясности:

не путайте с u.EndDate.Value и inv.EndDate.Value

вот истинная часть для u.EndDate.Hasvalue:

 IIf((u.StartDate.Value >= inv.StartDate.Value And u.StartDate.Value <= inv.EndDate.Value) Or _
                                                (u.EndDate.Value >= inv.StartDate.Value And u.EndDate.Value <= inv.EndDate.Value) Or _
                                                (u.StartDate.Value < inv.StartDate.Value And u.EndDate.Value > inv.EndDate.Value), True, False)

а вот и фальшивая часть

IIf(u.StartDate.Value <= inv.EndDate.Value, True, False)

Ответы [ 3 ]

5 голосов
/ 25 августа 2011
  • Используйте If вместо IIf.Это короткое замыкание (как условный оператор C #) и будет работать, потому что условия только оцениваются , если HasValue равно True.IIf устарело.Никогда не используйте его.

  • Более того, выражение типа If(condition, True, False) не имеет смысла.Замените его на condition.

  • Наконец, вам нужно использовать AndAlso вместо And - еще раз, чтобы произошло короткое замыкание.Фактически, всегда используют AndAlso и OrElse в условных выражениях.Используйте And и Or только при выполнении битовых операций.

  • DirectCast также не требуется.

Это оставляет нам очень упрощенное выражение:

If(Not u.EndDate.HasValue, u.StartDate.Value <= inv.EndDate.Value), _
    (u.StartDate.Value >= inv.StartDate.Value AndAlso u.StartDate.Value <= inv.EndDate.Value) OrElse _
    (u.EndDate.Value >= inv.StartDate.Value AndAlso u.EndDate.Value <= inv.EndDate.Value) OrElse _
    (u.StartDate.Value < inv.StartDate.Value AndAlso u.EndDate.Value > inv.EndDate.Value))

Но это выражение все еще слишком сложно.Вы должны разбить это на части, но сначала присвойте значения внутри обнуляемых значений некоторой временной переменной, используя Let внутри запроса.

1 голос
/ 25 августа 2011

IIF оценивает оба результата, даже если возвращает только один.Поэтому, если один результат вызовет исключение (например, доступ к .Value обнуляемого значения, когда его нет), вы получите ошибку, даже если вы проверите .HasValue в начале IIF

0 голосов
/ 25 августа 2011

Просто чтобы расширить оценку ИИФ для обеих частей.

Попробуйте код наподобие этого:

IIF (True, msgbox("True"), msgbox("false"))

Вы получите два окна сообщений. Тот, который говорит «Правда» и тот, который говорит «ложь». Даже если ясно, что вы должны активировать только секцию True.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...