Entity Framework - usuwanie wszystkich dzieci z korzenia drzewa wielopoziomowego

0

Cześć, to znowu ja :(
Przechodząc od razu do sedna sprawy to problem mam z usuwaniem wszystkich dzieci z korzenia drzewa wielopoziomowego z wykorzystaniem Entity Framework.

using (var context = new TreeDBtestEntities())
            {
                using(var dbContextTransaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        RemoveWithChildren(context.DynamicTrees.Where(x => x.Id == id).FirstOrDefault());
                        context.SaveChanges();
                        dbContextTransaction.Commit();
                    }
                    catch
                    {
                        dbContextTransaction.Rollback();
                    }
                }
            }
public static void RemoveWithChildren(DynamicTree source)
        {
            using (var context = new TreeDBtestEntities())
            {
                var a = context.DynamicTrees.Where(c => c.ParentId == source.Id);
                context.DynamicTrees.RemoveRange(a);
                context.DynamicTrees.Remove(source);
                context.SaveChanges();
            }
        }

Z góry dziękuję za odpowiedzi!

0

Jakiś wyjątek dostajesz? Ogólnie musisz włączyć kaskadowe usuwanie po stronie bazy. Używasz code first w ef ?

0

{"The object cannot be deleted because it was not found in the ObjectStateManager."}
Bazę najpierw miałem stworzoną.

Przykładowo baza wygląda tak: title
Ogólnie jest to tylko jedna tabela.

0

czemu tworzysz 2 różne contexty? Zrób to w jednym, rozdzielenie tego na metody nie ma większego sensu.

0

Ok racja rozbiłem to ponieważ chciałem zrobić to rekurencyjnie. Teraz jest w jednym contexcie ale takie rozwiązanie niby działa ale działa ale nie do końca, ponieważ nie usuwa głębszych rekordów. Mogę to rozrysować jeśli trzeba.

0

używasz trybu Code First czy Db First?

0

Db first, już wspomniałem, że najpierw zrobiłem bazę i na podstawie bazy wygenerowałem wszystko ;)

0

Wklej poprawiony kod i tą klasę Tree

0
    public partial class DynamicTree
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Nullable<int> ParentId { get; set; }
    }
using (var context = new TreeDBtestEntities())
            {
                using(var dbContextTransaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        var source = context.DynamicTrees.Where(x => x.Id == id).FirstOrDefault();
                        var a = context.DynamicTrees.Where(c => c.ParentId == source.Id);
                        context.DynamicTrees.RemoveRange(a);
                        context.DynamicTrees.Remove(source);
                        context.SaveChanges();
                        dbContextTransaction.Commit();
                    }
                    catch(Exception ex)
                    {
                        var a = ex;
                        dbContextTransaction.Rollback();
                    }
                }
            }

Edit:// Myślałem też nad takim czymś ale nie da się operować na liście, którą wykorzystuje foreach

List<int> idPar = new List<int>();
                        idPar.Add(id);
                        foreach (int item in idPar)
                        {
                            var record = context.DynamicTrees.Where(c => c.ParentId == item);
                            idPar.Add(record.First().Id);
                            context.DynamicTrees.RemoveRange(record);
                            idPar.Remove(item);
                        }

Edit2://
Prawie rozwiązane, została sama głowa do usunięcia

List<int> idPar = new List<int>();
                        idPar.Add(id);
                        int count = idPar.Count();
                        for (int i = 0; i<count;i++)
                        {
                            var item = idPar[i];
                            var record = context.DynamicTrees.Where(c => c.ParentId == item);
                            if (record.FirstOrDefault() != null)
                            {
                                foreach (var leaf in record)
                                {
                                    idPar.Add(leaf.Id);
                                }

                                
                                i = -1;
                            }
                            context.DynamicTrees.RemoveRange(record);
                            idPar.Remove(item);
                            count = idPar.Count();
                            if (count > 0)
                                i = -1;
                        }
0

Ten algorytm nie ma sensu. EF spokojnie sobie z tym poradzi. Czemu tą klasę modelu masz oznaczoną jako partial? Druga sprawa to w modelu powinieneś oznaczyć klucz prywatny atrybutem Key. Trzecia sprawa to ta transakcja jest też zbędna.

0

EF sam wygenerował partial, EF sam sobie może by i poradził jednak w jaki sposób to nie wiem, nie znalazłem innego rozwiązania. Jeśli chodzi o transakcje to tak się nauczyłem, że w razie niepowodzenia nie usunie części rekordów, nie tak jest?

1 użytkowników online, w tym zalogowanych: 0, gości: 1