Entity Framework, Setup для легкой итерации и общих ссылок на многоуровневую иерархию - PullRequest
0 голосов
/ 22 мая 2018

У меня есть установки модели структуры сущностей следующим образом:

-TblProject
--TblLine
---TblGroup
----TblStation
-----TblDevice
------TblSubDevice
-------TblSubSubDevice

Каждый из этих классов реализует BaseTable, который содержит свойства ID, Name и Type.Я могу привести любую из моих сущностей в качестве BaseTable и получить доступ к этим свойствам.

У меня есть ситуация, когда мне приходится писать повторяющийся код только потому, что каждый класс имеет свой тип, см. Эту функцию сортировки, например:

        public static void OrderTreeSetup(ObservableCollection<tblProject> Table, System.ComponentModel.ListSortDirection direction)
    {
        ICollectionView ParentTable = CollectionViewSource.GetDefaultView(Table);
        ParentTable.SortDescriptions.Clear();
        ParentTable.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
        foreach (tblProject Project in Table)
        {
            ICollectionView Projects = CollectionViewSource.GetDefaultView(Project.tblLines);
            Projects.SortDescriptions.Clear();
            Projects.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
            foreach (tblLine Line in Project.tblLines)
            {
                ICollectionView Lines = CollectionViewSource.GetDefaultView(Line.tblGroups);
                Lines.SortDescriptions.Clear();
                Lines.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
                foreach (tblGroup Group in Line.tblGroups)
                {
                    ICollectionView Groups = CollectionViewSource.GetDefaultView(Group.tblStations);
                    Groups.SortDescriptions.Clear();
                    Groups.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
                    foreach (tblStation Station in Group.tblStations)
                    {
                        ICollectionView Stations = CollectionViewSource.GetDefaultView(Station.tblDevices);
                        Stations.SortDescriptions.Clear();
                        Stations.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
                        foreach (tblDevice Device in Station.tblDevices)
                        {
                            ICollectionView Devices = CollectionViewSource.GetDefaultView(Device.tblSubDevices);
                            Devices.SortDescriptions.Clear();
                            Devices.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
                            foreach (tblSubDevice SubDevice in Device.tblSubDevices)
                            {
                                ICollectionView SubDevices = CollectionViewSource.GetDefaultView(SubDevice.tblSubSubDevices);
                                SubDevices.SortDescriptions.Clear();
                                SubDevices.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", direction));
                            }
                        }
                    }
                }
            }

        }
    }

Как я могу изменить модель своей сущности, чтобы обеспечить средства для более общего программирования?

1 Ответ

0 голосов
/ 23 мая 2018

В вашем коде действительно есть место для оптимизации (как и следовало ожидать, когда вы увидите такое количество повторяющегося кода).Это может быть сделано даже при относительно небольших усилиях.

Давайте начнем с низко висящих фруктов: поскольку CollectionViewSource.GetDefaultView принимает параметр типа object, вы можете заменить свой код инициализации ...

ICollectionView ParentTable = CollectionViewSource.GetDefaultView(Table);
ParentTable.SortDescriptions.Clear();
ParentTable.SortDescriptions
    .Add(new System.ComponentModel.SortDescription("Name", direction));

... при вызове этого метода:

private static void ConfigureSorting(object entity, ListSortDirection direction)
{
    ICollectionView view = CollectionViewSource.GetDefaultView(entity);
    view.SortDescriptions.Clear();
    view.SortDescriptions.Add(new SortDescription("Name", direction));
}

Что бы сделать ваш код инициализации более чистым и избежать проблем с обслуживанием повторяющихся частей вашего кода:

public static void OrderTreeSetup(ObservableCollection<tblProject> table,
    ListSortDirection direction)
{
    ConfigureSorting(table, direction);
    foreach (tblProject project in table)
    {
        ConfigureSorting(project.tblLines, direction);
        foreach (tblLine line in project.tblLines)
        {
            //...etc...
        }
    }
}

Это, однако, не конец строки.Поскольку вы можете применять интерфейсы к вашим сгенерированным (в случае базы данных или модели в первую очередь) или самописным (в случае кода вначале) объектам POCO, вы можете создать интерфейс, который позволит рекурсивную конфигурацию ваших объектов:

interface ICascadingSetup
{
   IEnumerable<object> Children { get; }
}

Вы можете применить этот интерфейс ко всем POCO, у которых есть дочерние элементы, которые разрешают настройку (это будет все за исключением TblSubSubDevice):

partial class TblProject : ICascadingSetup
{
    IEnumerable<object> ICascadingSetup.Children => tblLines;
}

//...etc...

Теперь вы можете ввестирекурсивный метод, который будет выполнять инициализацию:

public static void OrderTreeSetup(ObservableCollection<tblProject> table,
    ListSortDirection direction)
{
    ConfigureSortingRecursive(table, direction);
    //...all further initializations you need to do...
}

private static void ConfigureSortingRecursive(IEnumerable<object> entities,
    ListSortDirection direction)
{
    ICollectionView view = CollectionViewSource.GetDefaultView(entities);
    view.SortDescriptions.Clear();
    view.SortDescriptions.Add(new SortDescription("Name", direction));
    foreach (object entity in entities) {
        if (entity is ICascadingSetup cascadingSetup) {
            ConfigureSortingRecursive(cascadingSetup.Children, direction);
        }
    }
}

Всякий раз, когда у вас есть это древовидное представление похожих объектов, всегда стоит проверить, является ли рекурсия опцией, упрощающей вещи.

...