IEnumerable <T>GroupBy с быстрой проверкой - PullRequest
0 голосов
/ 11 января 2019

Поэтому проблема, которую я пытаюсь решить, состоит в том, что я использую множество универсальных классов с <T>, которым необходимо выполнить вызов REST .NET Async для получения списка IEnumerable<T> объектов из API. Во время выполнения все хорошо решается с T, потому что у меня есть несколько конкретных примеров выше по цепочке.

У меня рабочий класс:

public class Worker<T> where T : class, new()

Имеет фабрику клиентов REST:

IBatchClientFactory batchClientFactory

где на этой фабрике в основном создается экземпляр этого:

public class BatchClient<T> where T : class, new()

У BatchClient есть важный метод:

public BaseBatchResponse<T> RetrieveManyAsync(int top = 100, int skip = 0)

так что метод рабочего класса делает что-то вроде:

var batchClient = this.batchClientFactory.Create<T>(siteId);
var batchResponse = await batchClient.RetrieveManyAsync(top, skip);

Пакетный ответ выглядит так:

public class BaseBatchResponse<T>
{
    public List<T> Value { get; set; }

    public BaseBatchResponse<T> Combine(BaseBatchResponse<T> baseBatchResponse)
    {
        return new BaseBatchResponse<T>
        {
            Value = this.Value.Concat(baseBatchResponse.Value).ToList()
        };
    }
}

Теперь во время выполнения все в порядке, потому что выше по цепочке я создаю экземпляр Worker во что-то вроде ... new Worker<Appointment>(); И все T просто будут отлично работать, так как все в цепочке просто делает дженерики.

Моя проблема сейчас в том, что я хотел бы оценить свой batchResponse, пройти по списку и выполнить некоторую проверку для каждого элемента в списке. Я видел эту статью о переполнении стека , которая, кажется, позволяет разделить список на 2 списка с помощью GroupBy через словарь, где некоторые SomeProp - это то, что вы разбиваете вокруг ... но вы можете сделать эту логику GroupBy, используя вызов метода? И что более важно, я могу использовать FluentValidation в качестве вызова этого метода? В идеале мой код должен выглядеть так:

var groups = allValues.GroupBy(val => validationService.Validate(val)).ToDictionary(g => g.Key, g => g.ToList());
List<T> valids = groups[true];
List<T> invalids= groups[false];

Где результатом будет список моих объектов, которые являются действительными, и второй список моих объектов, которые являются недействительными.

В идеале я бы просто создал класс FluentValidation, который связывается с моим конкретным классом Appointment и в нем есть правило:

this.When(x => !string.IsNullOrWhiteSpace(x.Description), () => 
            this.RuleFor(x => x.Description).Length(1, 4000));

, который соединит все вместе и будет использоваться для определения того, принадлежит ли мой объект во время выполнения в списке допустимых или недействительных

1 Ответ

0 голосов
/ 11 января 2019

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

using System.Collections.Generic;
using System.Linq;

namespace Investigate.Samples.Linq
{
    class Program
    {
        public class SomeEntity
        {
            public string Description { get; set; }
        }

        static void Main(string[] args)
        {
            //Mock some entities
            List<SomeEntity> someEntities = new List<SomeEntity>()
            {
                new SomeEntity() { Description = "" },
                new SomeEntity() { Description = "1" },
                new SomeEntity() { Description = "I am good" },
            };

            //Linq: Where to filter out invalids, then category to result with  ToDictionary
            Dictionary<bool, SomeEntity> filteredAndVlidated = someEntities.Where(p => !string.IsNullOrWhiteSpace(p.Description)).ToDictionary(p => (p.Description.Length > 1));

            /* Output:
             *  False: new SomeEntity() { Description = "1" }
             *  True: new SomeEntity() { Description = "I am good" }
             * */
        }
    }
}

Кодовый сегмент:

Dictionary<bool, SomeEntity> filteredAndVlidated = someEntities.Where(p => !string.IsNullOrWhiteSpace(p.Description)).ToDictionary(p => (p.Description.Length > 1));
...