将Linq逻辑压缩为一个查询

时间:2018-01-05 20:18:05

标签: c# .net linq sorting intellisense

我将两个参数传递给方法,可以是帐号或组织号。只有一个参数可以一次具有一个值。这意味着,如果我传入一个帐号,则组织号为空。可见 - 反之亦然。

目前我正在尝试对与个人或组织相关联的帐户数组进行排序。我拿出与实体直接相关的帐户并对其进行排序。

// Accounts entity is directly involved with
mainAccounts = accounts
    .Where(acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PrimaryPersonNumber : acct.PrimaryOrganizationNumber) == entityNumber)
    .OrderBy(acct => acct.AccountNumber);

然后我查看附加到每个实体的RoleCode变量以对其进行排序。

我遇到的问题是尝试将这两个查询合并为一个,就像我对第一个查询所做的那样。

if (persNbr.HasValue)
{
    // Accounts Person takes a role in
    secondaryAccounts = accounts
                        .Where(acct => acct.PrimaryPersonNumber != entityNumber)
                        .OrderBy(acct => acct.PersonRoles
                                             .Where(role => role.PersNbr == entityNumber)
                                             .Select(role => role.RoleOrder).Min())
                        .ThenBy(acct => acct.AccountNumber);
}
else
{
    // Accounts Organization takes a role in
    secondaryAccounts = accounts
                        .Where(acct => acct.PrimaryOrganizationNumber != entityNumber)
                        .OrderBy(acct => acct.OrganizationRoles
                                             .Where(role => role.OrgNbr == entityNumber)
                                             .Select(role => role.RoleOrder).Min())
                        .ThenBy(acct => acct.AccountNumber);

我试图关注,但C#intellisense抱怨该对象(acct.PersonRolesacct.OrganizationRoles)不存在,并且直到运行时才赢了。

secondaryAccounts = accounts
    .Where(acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PrimaryPersonNumber : acct.PrimaryOrganizationNumber) != entityNumber)
    .OrderBy(acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PersonRoles : acct.OrganizationRoles) // <-- Intellisense can't get past this line
                     .Where(role => ((acct.PrimaryPersonNumber.HasValue) ? role.PersNbr : role.OrgNbr) == entityNumber)
                     .Select(role => role.RoleOrder).Min())
    .ThenBy(acct => acct.AccountNumber);

我该怎么做?

这是我的方法,如果它有帮助。

private Account[] SortAccountsOnPersonRoles(Account[] accounts, long? persNbr, long? orgNbr)
{
    IEnumerable<Account> mainAccounts;
    IEnumerable<Account> secondaryAccounts;

    long entityNumber = (long)((persNbr.HasValue) ? persNbr : orgNbr);

    // Accounts entity is directly involved with
    mainAccounts = accounts
        .Where(acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PrimaryPersonNumber : acct.PrimaryOrganizationNumber )== entityNumber)
        .OrderBy(acct => acct.AccountNumber);

    if (persNbr.HasValue)
    {
        // Accounts Person takes a role in
        secondaryAccounts = accounts
                            .Where(acct => acct.PrimaryPersonNumber != entityNumber)
                            .OrderBy(acct => acct.PersonRoles
                                                 .Where(role => role.PersNbr == entityNumber)
                                                 .Select(role => role.RoleOrder).Min())
                            .ThenBy(acct => acct.AccountNumber);
    }
    else
    {
        // Accounts Organization takes a role in
        secondaryAccounts = accounts
                            .Where(acct => acct.PrimaryOrganizationNumber != entityNumber)
                            .OrderBy(acct => acct.OrganizationRoles
                                                 .Where(role => role.OrgNbr == entityNumber)
                                                 .Select(role => role.RoleOrder).Min())
                            .ThenBy(acct => acct.AccountNumber);
    }

    return mainAccounts.Concat(secondaryAccounts).ToArray();
}

编辑:来自Intellisense的错误说:

  

无法确定条件表达式的类型,因为PersonRoles []和OrganizationRoles之间没有隐式转换[]

由于我试过的这句话,它正在发生:

.OrderBy(acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PersonRoles : acct.OrganizationRoles) // <-- Intellisense can't get past this line
     .Where(role => ((acct.PrimaryPersonNumber.HasValue) ? role.PersNbr : role.OrgNbr) == entityNumber)

Intellisense无法确定lamda变量的值来执行LINQ查询.Where()。具体来说,

acct => ((acct.PrimaryPersonNumber.HasValue) ? acct.PersonRoles : acct.OrganizationRoles)

1 个答案:

答案 0 :(得分:3)

试试这个:

首先,使用不同的参数创建两个单独的函数。

private Account[] SortAccountsOnPersonRolesByPersonNumber(Account[] accounts, 
    long personNbr) 

private Account[] SortAccountsOnPersonRolesByOrgNumber(Account[] accounts, 
    long orgNbr) 

然后,更改main函数,以便不是传递personNbrorgNbr的参数,而是计算哪些有值(如果两者都做,或者两者都做),则传递函数。 / p>

我不知道逻辑是什么,所以我给出的参数相当无意义。

private Account[] SortAccountsOnPersonRoles(Account[] accounts, 
    Func<Account, bool> accountComparison, 
    Func<Role, bool> roleComparison)

现在,您可以执行以下操作,而不是因为或两个条件不同而重复整个查询:

   secondaryAccounts = accounts
       .Where(acct => accountComparison(acct))
       .OrderBy(acct => acct.PersonRoles
       .Where(role => roleComparison(role))
           .Select(role => role.RoleOrder).Min())
       .ThenBy(acct => acct.AccountNumber);

现在从两个新功能中,调用&#34;内部&#34;函数并将这些条件作为参数传递。

private Account[] SortAccountsOnPersonRolesByPersonNumber(Account[] accounts, 
    long personNbr) 
{
    Func<Account, bool> accountComparison = acct => acct.PrimaryPersonNumber != personNbr;
    Func<Role, bool> roleComparison = role => role.PersNbr == personNbr;
    return SortAccountsOnPersonRoles(accounts, accountComparison, roleComparison);
}