Существует несколько сообщений ER. Я не знаком с тем, который вы используете, но достаточно ясно, что вы пытаетесь представить подтип (например, наследование, категорию, подкласс, иерархию обобщений ...). Это реляционный двоюродный брат наследования ООП.
При выполнении подтипов вы, как правило, занимаетесь следующими проектными решениями:
Vehicle
без , также являющийся 2WD
или 4WD
? 1 Vehicle
быть как 2WD
, так и 4WD
? 2 Bike
или Plane
(и т. Д.) Могут быть позже добавлены в модель базы данных? Обозначение Information Engineering различает включительно и исключительное отношение подтипа. Нозначение IDEF1X, с другой стороны, не распознает эту разницу (напрямую), но различает полный и неполный подтип (что не делает IE).
Следующая диаграмма из Справочник по методу ERwin (глава 5, Связывание подтипов) иллюстрирует разницу:
[/g9]
Ни IE, ни IDEF1X не позволяют прямо указывать абстрактные или конкретные parent.
К сожалению, практические базы данных напрямую не поддерживают наследование, поэтому вам понадобится transform эта диаграмма для реальных таблиц. Для этого обычно существует 3 подхода:
2WD
и 4WD
с одинаковым идентификатором). Можно легко обеспечить включение инклюзивных против эксклюзивных детей и абстрактных против конкретного родителя (просто изменяя ПРОВЕРКУ). Минусы: Некоторые запросы могут быть медленнее, поскольку они должны отфильтровывать «неинтересные» дети. В зависимости от вашей СУБД ограничения, специфичные для ребенка, могут быть проблематичными. Многие NULL могут хранить данные о хранении. Менее подходит для неполного подтипирования - добавление нового ребенка требует изменения существующей таблицы, что может быть проблематичным в производственной среде. Как вы можете видеть, ситуация не идеальна - вам нужно идти на компромисс независимо от того, какой подход вы выберете. Подход (3), вероятно, должен быть вашей отправной точкой и выбирать только одну из альтернатив, если для этого есть веская причина.
1 Я предполагаю, что это то, что толщина линии соответствует вашим диаграммам.
2 Я предполагаю, что это означает наличие или отсутствие «непересекающихся» на ваших диаграммах.
Они уже выглядят очень похожими на расширения в 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>
.
Согласно этой ссылке Функциональное программирование в C# 3.0: То, как Отображаются/Уменьшают/Фильтруют, может Rock Ваш Мир , следующее является эквивалентом в C# под Системой. Пространство имен Linq:
Вы могли бы хотеть добавить способ сделать, карта, но возвратить новый список, вместо того, чтобы работать над списком передала в (и возвратить список может оказаться полезным для объединения в цепочку других операций)..., возможно, перегруженная версия с булевской переменной, которая указывает, хотите ли Вы возвратить новый список или нет, как таковые:
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;
}
Я использовал бы созданный в делегатах 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);
}