Как эффективно получать результаты из Linq с или без ввода параметров пользователем - PullRequest
0 голосов
/ 11 октября 2019

У меня есть запрос linq, который я хотел бы вернуть результаты с введенными пользователем данными. Однако, если эта функция вызывается и пользователь получает нулевые данные, ИЛИ пользователь просто хочет выполнить поиск по данным, ИЛИ только один из других параметров, как я могу эффективно написать linq для этого? Вот Linq и функция:

public static List<Objects.Logs.GenericLog> GetLogs(int entityId, int logLevelId, 
    DateTime startDate, DateTime endDate)
{
    var logsList = new List<Objects.Logs.GenericLog>();

    using(var db = CORAContext.GetCORAContext())
    {
        logsList = (from i in db.GenericLog select  new Objects.Logs.GenericLog()
        {
            EntityId = i.FkEntityId,
            LogSourceCode = i.FkLogSourceCode,
            LogLevelId = i.FkLogLevelId,
            LogDateTime = i.LogDateTime,
            LogId = i.PkLogId,
            Message = i.Message
        })
        .Where(i => i.LogDateTime >= startDate && i.LogDateTime <= endDate)
        .Where(i => i.EntityId == entityId || i.EntityId == null)
        .Where(i => i.LogLevelId == logLevelId || i.EntityId == null)
        .ToList();
    }

    return logsList;
}

Например, во втором и третьем Where () у меня есть ||i.EntityId == null ... думая, что это будет соответствовать, если пользовательский ввод для Entity равен null?

Будет ли это работать?

Кроме того, как я могу сделать это для диапазонов дат? Могу ли я сделать то же самое?

Наконец, есть ли ЛУЧШИЙ способ сделать это?

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

Если я вас правильно понимаю, у вас есть метод, который получает отфильтрованный набор данных на основе значений переданных параметров. Но вы хотите сделать параметры необязательными, поэтому, если пользователь хочет данные для всех объектов, онине передал бы entityId.

Если это так, то вы можете сделать аргументы необязательными, указав для них значение по умолчанию в сигнатуре метода. Затем мы можем проверить, имеет ли аргумент значение по умолчанию, и если он есть, не применять этот фильтр;в противном случае примените его.

Мы можем сделать это, выполнив .Where(x => argHasDefaultValue || someFilter). Это работает, потому что если аргумент имеет значение по умолчанию, то вторая часть || игнорируется.

Например:

public static List<Objects.Logs.GenericLog> GetLogs(int entityId = int.MinValue, 
    int logLevelId = int.MinValue, DateTime startDate = default(DateTime), 
    DateTime endDate = default(DateTime))
{
    using(var db = CORAContext.GetCORAContext())
    {
        return db.GenericLog
            .Where(i => startDate == default(DateTime) || i.LogDateTime >= startDate)
            .Where(i => endDate == default(DateTime) || i.LogDateTime <= endDate)
            .Where(i => entityId == int.MinValue || i.EntityId == entityId)
            .Where(i => logLevelId == int.MinValue || i.LogLevelId == logLevelId)
            .Select(i => new Objects.Logs.GenericLog
            {
                EntityId = i.FkEntityId,
                LogSourceCode = i.FkLogSourceCode,
                LogLevelId = i.FkLogLevelId,
                LogDateTime = i.LogDateTime,
                LogId = i.PkLogId,
                Message = i.Message
            }).ToList();
    }
}
2 голосов
/ 11 октября 2019

Разделение, создание запроса и генерация окончательного результата по .ToList() Когда вы генерируете запрос, вы можете добавить операторы по запросу, например, так:

    public static List<Objects.Logs.GenericLog> GetLogs(int entityId, int logLevelId, DateTime startDate, DateTime endDate)
        {
            var logsList = new List<Objects.Logs.GenericLog>();

            using(var db = CORAContext.GetCORAContext())
            {

                var query = (from i in db.GenericLog select  new Objects.Logs.GenericLog()
                {
                    EntityId = i.FkEntityId,
                    LogSourceCode = i.FkLogSourceCode,
                    LogLevelId = i.FkLogLevelId,
                    LogDateTime = i.LogDateTime,
                    LogId = i.PkLogId,
                    Message = i.Message
                });
                if(someCondition) {
                     query = query.Where(i => i.LogDateTime >= startDate && i.LogDateTime <= endDate)
                }
                query = query.Where(i => i.EntityId == entityId || i.EntityId == null)
                query = query.Where(i => i.LogLevelId == logLevelId || i.EntityId == null)
                logsList = query.ToList();

            }

            return logsList;
        }
...