有条件的地方加入

时间:2012-11-29 16:19:14

标签: sql vb.net linq

我需要使用LINQ返回与提供的标识字段匹配的客户端列表,这些字段位于单独的表中。如果SQL语句位于存储过程中,则它将如下所示:

Select client.*
From ADLT_Clients as client
    Inner Join ADLT_ClientIdentifiers as identifier
        on client.ClientPIN = identifier.ClientPIN
Where identifier.EmailAdrs = @EmailAddress
    and identifier.FBINum = @FBINumber
    (...)

我正在尝试使用以下内容在LINQ中执行此操作:

    Public Function FindByIndentifiers(adultClient As AdultClient) As List(Of AdultClient)
        Dim adultClients As New List(Of AdultClient)
        Dim clients = From client As ADLT_Client In _cmisiiEntities.ADLT_Clients
                      Join identifier In _cmisiiEntities.ADLT_ClientIdentifiers On client.ClientPIN Equals identifier.ClientPIN
                      Select client

        If adultClient.AdultClientIdentifiers IsNot Nothing Then
            With adultClient.AdultClientIdentifiers
                If Not String.IsNullOrEmpty(.EmailAddress) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.EMailAdrs.Contains(.EmailAddress))
                If Not String.IsNullOrEmpty(.FBINumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.FBINum.Contains(.FBINumber))
                If Not String.IsNullOrEmpty(.ICOTSNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.ICOTSNum.Contains(.ICOTSNumber))
                If Not String.IsNullOrEmpty(.InmateNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.InmateNum.Contains(.InmateNumber))
                If Not String.IsNullOrEmpty(.LicenseNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.LicenseNum.Contains(.LicenseNumber))
                If Not String.IsNullOrEmpty(.LicenseNumberState) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.LicenseNumState.Contains(.LicenseNumberState))
                If Not String.IsNullOrEmpty(.PassportNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.PassportNum.Contains(.PassportNumber))
                If Not String.IsNullOrEmpty(.AlienRegistrationNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.GreenCardNum.Contains(.AlienRegistrationNumber))
                If Not String.IsNullOrEmpty(.SocialSecurityNumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.SSN.Contains(.SocialSecurityNumber))
                If Not String.IsNullOrEmpty(.SPBINumber) Then clients = clients.Where(Function(f) f.ADLT_ClientIdentifiers.SPBINum.Contains(.SPBINumber))
            End With
        End If

        For Each client In clients.Take(100).ToList()
            adultClients.Add(BuildAdultClient(client))
        Next

        Return adultClients
    End Function

当此代码在没有有效参数的情况下执行时,不会添加任何where子句,并且clients.Take(100).ToList()语句执行正常。如果我包含任何有效参数,从而添加了where子句,则该语句在ToList()调用上给出NullReferenceException。

我的理论是,我试图添加的where子句存在别名问题。当where子句是初始语句的一部分时,我使用join语句创建的标识符别名。如果我将我的陈述修改为:

            Dim clients = (From client As ADLT_Client In _cmisiiEntities.ADLT_Clients
                      Join identifier In _cmisiiEntities.ADLT_ClientIdentifiers On client.ClientPIN Equals identifier.ClientPIN) _
                      .Where(Function(f) f.identifier.EMailAdrs.Contains(adultClient.EmailAddress)) _
                      .Select(Function(f) f.client)

代码也会执行。这里的不同之处在于我将浏览已定义的标识符别名。我不能在条件where语句中执行相同的f.identifier.EmailAdrs,因为标识符不是该上下文的一部分?

我在这里遗漏了什么,有没有更好的方法来正确地做到这一点,或者这是VB的限制?

1 个答案:

答案 0 :(得分:0)

如果我在linqPad中使用linq2Sql

执行此操作
Dim c as new Config with {.Category="Other"}
Dim q =from c1 in  Configs select c1

if(c isnot nothing) then
    if not string.isnullorempty(c.Category) then q=q.Where(Function(f) f.Category.Contains(c.Category))
end if
q.Dump()

它可以工作,但是如果我这样做

Dim c as new Config with {.Category="Other"}
Dim q =from c1 in  Configs select c1

if(c isnot nothing) then
    with c
        if not string.isnullorempty(.Category) then q=q.Where(Function(f) f.Category.Contains(.Category))
    end with
end if
q.Dump()

它抛出一个空引用异常。我认为这是你的条款与表达式冲突