Вложенные IEnumerable коллекции в классе фильтрации по нескольким условиям - PullRequest
0 голосов
/ 05 октября 2018

Возможно, я не использую правильный термин "вложенный", но вы можете увидеть 2 класса, которые у меня есть ниже.IEnumerable<OperationTask> находится в IEnumerable<AxApp>.

Я надеюсь, что смогу объяснить это правильно:

  1. У меня есть метод, который читает значения из текстового файла в строку []

    string[] appNames = _appNamesRepository.GetAppNameListFromInputFile(fileName);
    
  2. Затем я создаю коллекцию IEnumerable<AxApp> с методом, который читает таблицу SQL и возвращает свойства AxApp для каждого значения приложения в текстовом файле.

    IEnumerable<AxApp> allAxApps = _axAppRepository.GetAllAxAppsInList(appNames);
    
  3. Мне нужно отфильтровать коллекцию IEnumerable<AxApp> на основе определенных критериев из значений в IEnumerable<OperationTask>.Я могу заставить работать простой лямбда-поиск, но не могу вернуть правильный результат, если у меня больше пары значений, на которых я базируюсь.

Например, приведенный нижевернет IEnumerable<AxApp>, только если appid, operationType и operationStatus.Incomplete НЕ находятся в IEnumerable<OperationTasks>.

var test = allAxApps.Where(app => 
              !app.operationTasks
                     .Any(task => task.appId == app.appid && 
                                  task.operationType == operationType &&
                                  task.operationStatus != Status.Incomplete));

ОДНАКО, мне нужно пойти на шаг дальше, если operationType == "Дифференциал", я могу только вернуть AxApp, ЕСЛИ В IEnmerable<OperationTask> есть коллекция, где type = "NewConversion", status = "Complete", но НЕТ type = "Finish", но может включать в себя types = "diffrential"

public class AxApp
{
    public AxApp()
    {

    }
    public AxApp(int id, string appname, string dlname)
    {
        this.appname = appname;
        appid = id;
        this.dlname = dlname;
    }
    public string appname { get; set; }
    public int appid { get; set; }
    public string dlname { get; set; }
    public string dtname { get; set; }
    public int flags { get; set; }
    public IEnumerable<AxDlsd> dlsdRecords { get; set; }
    public IEnumerable<AxDl> dlRecords { get; set; }
    public IEnumerable<OperationTask> operationTasks { get; set; }
    public DateTime startMerge { get; set; }
    public DateTime endMerge { get; set; }
}


public class OperationTask
{
    public int operationId { get; set; }
    public int appId { get; set; }
    public OperationType operationType { get; set; }
    public Status operationStatus { get; set; }
    public DateTime startTime { get; set; }
    public DateTime endTime { get; set; }
}

Метод, который возвращает AppData из любого значения в строке []

public IEnumerable<AxApp> GetAllAxAppsInList(string[] appNamesInput)
{
    string query = @"SELECT appid, appname, dlname, dtname, flags FROM dbo.ae_apps WHERE appname = @_appname";
    string opQuery = @"SELECT operationId, appId, operationType, operationStatus, startTime, endTime FROM dbo.RDS_ConversionOperationsHistory WHERE appid = @_appId";

    using (var connection = _dbConnectionFactory.GetAxDbConnection())
    {
        foreach (string appname in appNamesInput)
        {
            AxApp result = connection.QuerySingle<AxApp>(query, new { _appname = appname });
            result.operationTasks = connection.Query<OperationTask>(opQuery, new { _appId = result.appid });
            yield return result;
        }
    }
}

IEnumerable for AxApp / OperationTask

[0] = {RDS.Conversion.UtilityLibrary.Models.AxApp}

    [0] {RDS.Conversion.UtilityLibrary.Models.AxApp}    RDS.Conversion.UtilityLibrary.Models.AxApp
    appid   1   int
    appname "PLIC_CENT_1"   string
    dlRecords   null    System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.AxDl
    dlname  "ae_dlsd1_SIM"  string
    dlsdRecords null    System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.AxDlsd>
    dtname  "ae_dt1"    string
    endMerge    {1/1/0001 12:00:00 AM}  System.DateTime
    flags   16384   int
    operationTasks  Count = 3   System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.OperationTask> {System.Collections.Generic.List<RDS.Conversion.UtilityLibrary.Models.OperationTask>}
    startMerge  {1/1/0001 12:00:00 AM}  System.DateTime


    operationTasks  Count = 3   System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.OperationTask> {System.Collections.Generic.List<RDS.Conversion.UtilityLibrary.Models.OperationTask>}





    [0] {RDS.Conversion.UtilityLibrary.Models.OperationTask}    RDS.Conversion.UtilityLibrary.Models.OperationTask
    appId   1   int
    endTime {1/1/0001 12:00:00 AM}  System.DateTime
    operationId 18  int
    operationStatus Complete    RDS.Conversion.UtilityLibrary.Models.Status
    operationType   NewConversion   RDS.Conversion.UtilityLibrary.Models.OperationType
    startTime   {9/28/2018 12:53:51 PM} System.DateTime

1 Ответ

0 голосов
/ 05 октября 2018

Я не уверен, что это то, что вы ищете, но это может привести вас в правильном направлении.

        test = allAxApps.Where(app =>
        {
            var tasks = app.operationTasks.ToList();
            var differentialCondition = false;

            if (operationType == OperationType.Differential)
            {
                var hasCompletedNewConversion = tasks.Any(task =>
                    task.operationType == OperationType.NewConversion &&
                    task.operationStatus == Status.Complete);

                var hasFinish = tasks.Any(task => task.operationType == OperationType.Finish);

                differentialCondition = hasCompletedNewConversion && !hasFinish;
            }

            var hasIncomplete = tasks.Any(task =>
                task.appId == app.appid &&
                task.operationType == operationType &&
                task.operationStatus == Status.Incomplete);

            return differentialCondition && !hasIncomplete;
        });
...