在linq查询where子句中的vb.net iif条件

Ken*_*Ken 2 linq vb.net sharepoint-2010

以下查询有什么问题,我收到此错误: Nullable对象必须有一个值.

  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)
Run Code Online (Sandbox Code Playgroud)

如果我在条件中删除了u.EndDate.Value,那么它可以正常工作.

这是堆栈跟踪:

在System.Nullable 1.get_Value() at SDBReports.InvoiceAllocationReportUserControl._Lambda$__4(VB$AnonymousType_02 $ VB $ It)at System.Linq.Enumerable.WhereEnumerableIterator 1.MoveNext() at System.Linq.Lookup2.Cileate [TSource](IEnumerable 1 source, Func2 keySelector,Func 2 elementSelector, IEqualityComparer1 4.GetEnumerator() at System.Linq.Enumerable.WhereSelectEnumerableIteratorcomparer )在System.Linq.GroupedEnumerable 2.MoveNext()在System.Linq.SystemCore_EnumerableDebugView `1.get_Items()

ps我使用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)
Run Code Online (Sandbox Code Playgroud)

这是假的部分

IIf(u.StartDate.Value <= inv.EndDate.Value, True, False)
Run Code Online (Sandbox Code Playgroud)

Kon*_*lph 5

  • If而不是IIf.这是短路的(就像C#的条件运算符一样)并且可以工作,因为条件 HasValue被评估被评估True.IIf已弃用.永远不要使用它.

  • 此外,表达If(condition, True, False)是无意义的.只需更换它condition.

  • 最后,您需要使用AndAlso而不是And- 再次,短路发生.事实上,总是使用AndAlsoOrElse条件.使用AndOr 做位运算的时候.

  • 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))
Run Code Online (Sandbox Code Playgroud)

但这种表达方式仍然过于复杂.您应该将其拆分,但首先使用Let查询内部将nullables中的值分配给某个临时变量.