Linq-to-Sql: рекурсивно получите детей

Операции со строками часто работают лучше на матрицах. Чтобы избежать хлопот gather/spread, я бы извлек столбцы R_, использовал apply (неявно преобразуя в матрицу) и затем присвоил результат обратно исходным данным:

При этом данные не кажутся очень аккуратными. Возможно, вам лучше gather использовать длинный формат и сохранять его длинным.

result = dd %>% ungroup %>%
  select(starts_with("R_")) %>%
  apply(1, cumsum) %>% 
  t

dd[, grepl("^R_", names(dd))] = result

dd
# # A tibble: 12 x 14
# # Groups:   LoB [1]
#    LoB      AY   R_0    R_1    R_2    R_3    R_4    R_5    R_6    R_7    R_8    R_9   R_10   R_11
#    <fct> <dbl> <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#  1 1      1994 50135 126766 155529 155529 171962 178263 178263 178263 178263 178263 178263 178263
#  2 1      1995 46530  51438  54072  55481  55481  55481  55481  55481  55481  55481  55481  55481
#  3 1      1996 38295  68722  69096  69566  70002  70002  70002  70002  70002  70002  70002  70002
#  4 1      1997 12033  16301  16301  16301  16301  16301  16301  16301  16301  16301  16301  16301
#  5 1      1998 13332  15326  15542  15745  15947  16126  16273  16408  16408  16408  16408  16408
#  6 1      1999 35064  83490  83490  83490  85605  85605  85605  85605  85605  85605  85605  85605
#  7 1      2000 15695  20280  20835  20835  20835  20835  20835  20835  20835  20835  20835  20835
#  8 1      2001 41227  56805  56805  56805  56805  56805  56805  56805  56805  56805  56805  56805
#  9 1      2002 88360  96472 103633 103633 103633 103816 103816 103816 103816 103816 103816 103816
# 10 1      2003 29500  60445  62637  64193  65464  66516  67498  68405  69307  70140  70940  71624
# 11 1      2004 30158  38299  38299  38299  38299  38299  38299  40655  40655  40655  40655  40655
# 12 1      2005 47589  59183  59955  60630  61165  61165  61165  61165  61165  61165  61165  61165
5
задан Rex M 2 May 2009 в 01:55
поделиться

1 ответ

Я, вероятно, использовал бы или UDF/CTE, или (для очень глубинных структур) хранимая процедура, которая делает то же вручную.

Обратите внимание, что, если можно изменить схему, можно предварительно индексировать такие рекурсивные структуры в, индексировал/расположился дерево, которое позволяет Вам сделать сингл МЕЖДУ запросом - но обслуживание дерева является дорогим (т.е. запрос становится дешевым, но вставьте/обновите/удалите, становятся дорогими, или Вам нужна отложенная запланированная задача).


Ре 2 - Вы можете только yield тип указан в перечислении ( T в IEnumerable<T> / IEnumerator<T>).

Вы могли yield IEnumerable<Comment> если возвращенный метод IEnumerable<IEnumerable<Comment>> - это имеет смысл?

Улучшения:

  • возможно, udf (для хранения composability, а не хранимой процедуры), который использует подход рекурсии CTE
  • использовать using, с тех пор DataContext IDisposable...

так:

using(var db = new MyDataContext() ) { /* existing code */ }
  • LoadWith стоит попытки, но я не уверен, что был бы полон надежд...
  • список искавших идентификаторов опасен как поле - я предполагаю, что Вы в порядке, пока Вы не называете его дважды... лично, я использовал бы аргумент на частном методе поддержки... (т.е. передал бы список между рекурсивными вызовами, но не на общедоступном API),
4
ответ дан 15 December 2019 в 01:12
поделиться
Другие вопросы по тегам:

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