这是写一个干净的函数吗?

时间:2017-12-20 13:47:18

标签: linq

我必须编写一个或多个功能,按角色,货币,公司和应用程序类型返回帐户。我决定根据请求模型返回过滤后的帐户创建一个函数。我的问题:这是实现该功能的一种干净方式吗?

public List<ResponseModel> Get(RequestModel requestModel)
{
    return (from role in Context.UserRoles
            where
                role.UserId == requestModel.UserId &&
                role.Account.CompanyId == requestModel.CompanyId &&
                (requestModel.RoleId == null ? true : role.RoleId == requestModel.RoleId) &&
                (requestModel.Currencies.Count() == 0 ? true : requestModel.Currencies.Contains(role.Account.Currency)) &&
                (requestModel.ApplicationTypes.Count() == 0 ? true : requestModel.ApplicationTypes.Contains(role.Account.Type)) &&
                (requestModel.AccountUse == null ? true : role.Account.AccountUse == requestModel.AccountUse) &&
                (requestModel.OperationTypeId == 0 ? true : role.OperationTypeId == requestModel.OperationTypeId) &&
                !role.Account.IsDeleted &&
                !role.Account.Company.IsDeleted
            orderby role.Account.FormattedAccount
            group role by role.Account into Accounts
            select new ResponseModel
            {
                Id = Accounts.Key.Id.ToString(),
                FormattedNumber = Accounts.Key.FormattedAccount,
                Number = Accounts.Key.Number,
                Currency = Accounts.Key.Currency,
                Application = Accounts.Key.Application
            }).ToList();
} 

我在想写一个返回相同的存储过程,但是在sql server上有近250个SP,并且这个函数被大量使用。 我也认为把它分成小功能,但我不知道这么做。

如果这有帮助:

public class RequestModel
{
    public int AccountId { get; set; }
    public int OperationTypeId { get; set; }
    public string RoleId {get; set;}
    public int CompanyId { get; set; }
    public string UserId { get; set; }
    public string AccountUse { get; set; }
    public List<string> Currencies { get; set; }
    public List<string> ApplicationTypes { get; set; } 
} 

1 个答案:

答案 0 :(得分:0)

您的解决方案是正确的,易于阅读和理解,其执行方面可能与它一样快。

我唯一要调整的是表格的条件

someCondition ? true : someOtherCondition

我会用等效的

替换它们
(someCondition || someOtherCondition)

where子句中删除条件表达式。我还会将collection.Count() == 0替换为!collection.Any(),如下所示:

return (from role in Context.UserRoles
        where
            role.UserId == requestModel.UserId &&
            role.Account.CompanyId == requestModel.CompanyId &&
            (requestModel.RoleId == null || role.RoleId == requestModel.RoleId) &&
            (!requestModel.Currencies.Any() || requestModel.Currencies.Contains(role.Account.Currency)) &&
            (!requestModel.ApplicationTypes.Any() || requestModel.ApplicationTypes.Contains(role.Account.Type)) &&
            (requestModel.AccountUse == null || role.Account.AccountUse == requestModel.AccountUse) &&
            (requestModel.OperationTypeId == 0 || role.OperationTypeId == requestModel.OperationTypeId) &&
            !role.Account.IsDeleted &&
            !role.Account.Company.IsDeleted
        orderby role.Account.FormattedAccount
        group role by role.Account into Accounts
        select new ResponseModel
        {
            Id = Accounts.Key.Id.ToString(),
            FormattedNumber = Accounts.Key.FormattedAccount,
            Number = Accounts.Key.Number,
            Currency = Accounts.Key.Currency,
            Application = Accounts.Key.Application
        }).ToList();

为了在RequestModel类中保留各种RequestModel属性的解释,您可以提供Filter属性,如下所示:

public class RequestModel {
    ...
    public Expression<Func<UserRole,bool>> Filter {
        get {
            return role =>
                (role.UserId == UserId)
            &&  (role.Account.CompanyId == CompanyId)
            &&  (RoleId == null || role.RoleId == RoleId)
            &&  (!Currencies.Any() || Currencies.Contains(role.Account.Currency))
            &&  (!ApplicationTypes.Any() || ApplicationTypes.Contains(role.Account.Type))
            &&  (AccountUse == null || role.Account.AccountUse == AccountUse)
            &&  (OperationTypeId == 0 || role.OperationTypeId == OperationTypeId);
        }
    }
}

where子句中使用它,如下所示:

return (from role in Context.UserRoles.Where(requestModel.Filter)
        where !role.Account.IsDeleted && !role.Account.Company.IsDeleted
        orderby role.Account.FormattedAccount
        group role by role.Account into Accounts
        select new ResponseModel {
            Id = Accounts.Key.Id.ToString(),
            FormattedNumber = Accounts.Key.FormattedAccount,
            Number = Accounts.Key.Number,
            Currency = Accounts.Key.Currency,
            Application = Accounts.Key.Application
        }).ToList();

请注意与requestModel相关的所有条件如何&#34;隐藏&#34;在RequestModel实例中。这样可以使将来对RequestModel的修改更容易,因为您不需要进行&#34;并行修改&#34;在代码的其他部分。