Универсальный Отображают/Уменьшают Расширения Списка в C#

Замечание ER

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

При выполнении подтипов вы, как правило, занимаетесь следующими проектными решениями:

  • Абстрактные против конкретного: может ли родитель инстанцирован? В вашем примере: существует ли Vehicle без , также являющийся 2WD или 4WD? 1
  • Inclusive vs. exclusive: может быть создано несколько дочерних элементов для тот же родитель? В вашем примере может Vehicle быть как 2WD, так и 4WD? 2
  • . Полноценный или неполный: вы ожидаете, что в будущем будет добавлено больше детей? В вашем примере ожидаете ли вы, что Bike или Plane (и т. Д.) Могут быть позже добавлены в модель базы данных?

Обозначение Information Engineering различает включительно и исключительное отношение подтипа. Нозначение IDEF1X, с другой стороны, не распознает эту разницу (напрямую), но различает полный и неполный подтип (что не делает IE).

Следующая диаграмма из Справочник по методу ERwin (глава 5, Связывание подтипов) иллюстрирует разницу:

enter image description here [/g9]

Ни IE, ни IDEF1X не позволяют прямо указывать абстрактные или конкретные parent.

Физическое представление

К сожалению, практические базы данных напрямую не поддерживают наследование, поэтому вам понадобится transform эта диаграмма для реальных таблиц. Для этого обычно существует 3 подхода:

  1. Поместить все классы в одну и ту же таблицу и оставить дочерние поля NULL. Затем вы можете иметь CHECK, чтобы убедиться, что правильное подмножество полей не равно NULL. Плюсы: Нет JOINING, поэтому некоторые запросы могут принести пользу. Могут применяться ключи на уровне родителя (например, если вы хотите избежать использования различных транспортных средств 2WD и 4WD с одинаковым идентификатором). Можно легко обеспечить включение инклюзивных против эксклюзивных детей и абстрактных против конкретного родителя (просто изменяя ПРОВЕРКУ). Минусы: Некоторые запросы могут быть медленнее, поскольку они должны отфильтровывать «неинтересные» дети. В зависимости от вашей СУБД ограничения, специфичные для ребенка, могут быть проблематичными. Многие NULL могут хранить данные о хранении. Менее подходит для неполного подтипирования - добавление нового ребенка требует изменения существующей таблицы, что может быть проблематичным в производственной среде.
  2. Поместите всех детей в отдельные таблицы, но у них нет таблицы для родителя (вместо этого повторяйте поля родителя и ограничения для всех детей). Имеет большинство характеристик (3), избегая при этом JOINs по цене меньшей ремонтопригодности (из-за всех этих повторений полей и ограничений) и невозможности принудительного использования ключей родительского уровня или представляет конкретного родителя.
  3. Поместите оба родителя и детей в отдельные таблицы. Плюсы: Чистота. Никакие поля / ограничения не должны быть искусственно повторяемы. Обеспечивает ключи родительского уровня и легко добавляет ограничения для конкретного ребенка. Подходит для неполного подтипирования (относительно легко добавить дополнительные таблицы для детей). Некоторым запросам может помочь только просмотр «интересных» дочерних таблиц. Минусы: Некоторые запросы могут быть JOIN-heavy. Может быть трудно обеспечить включение инклюзивных и эксклюзивных детей и абстрактных против конкретного родителя (они могут быть принудительно введены декларативно, если СУБД поддерживает круговые и отложенные внешние ключи, но принудительное их применение на уровне приложения обычно считается меньшее зло).

Как вы можете видеть, ситуация не идеальна - вам нужно идти на компромисс независимо от того, какой подход вы выберете. Подход (3), вероятно, должен быть вашей отправной точкой и выбирать только одну из альтернатив, если для этого есть веская причина.


1 Я предполагаю, что это то, что толщина линии соответствует вашим диаграммам.

2 Я предполагаю, что это означает наличие или отсутствие «непересекающихся» на ваших диаграммах.

26
задан BlackICE 26 February 2018 в 19:06
поделиться

4 ответа

Они уже выглядят очень похожими на расширения в Linq:

//takes a function that matches the Func<T,R> delegate
listInstance.Aggregate( 
    startingValue, 
    (x, y) => /* aggregate two subsequent values */ );

//takes a function that matches the Action<T> delegate
listInstance.ForEach( 
    x => /* do something with x */);

, Почему 2-й пример под названием, Преобразовывают? Вы намереваетесь изменить значения в списке так или иначе? Если это так, можно быть более обеспеченным использованием ConvertAll<T> или Select<T>.

35
ответ дан Keith 28 November 2019 в 06:10
поделиться

Согласно этой ссылке Функциональное программирование в C# 3.0: То, как Отображаются/Уменьшают/Фильтруют, может Rock Ваш Мир , следующее является эквивалентом в C# под Системой. Пространство имен Linq:

50
ответ дан Ray Vega 28 November 2019 в 06:10
поделиться

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

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
        params object [] args)
{
    return Transform(list, f, false, args);
}

public static List<T> Transform<T>(this List<T> list, TransformFunction<T> f,
        bool create, params object [] args)
{
    // Add code to create if create is true (sorry,
    // too lazy to actually code this up)
    foreach(var t in list)
         f(t,args);
    return list;
}
1
ответ дан Mike Stone 28 November 2019 в 06:10
поделиться

Я использовал бы созданный в делегатах Func вместо этого. Этот тот же код работал бы над любым IEnumerable. Ваш код превратился бы:

public static R Reduce<T,R>(this IEnumerable<T> list, Func<T,R> r, R initial)
{
     var aggregate = initial;
     foreach(var t in list)
         aggregate = r(t,aggregate);

     return aggregate;
}
public static void Transform<T>(this IEnumerable<T> list, Func<T> f)
{
    foreach(var t in list)
             f(t);
}
2
ответ дан Jake Pearson 28 November 2019 в 06:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: