none
Entity Framework Frage/Problem mit NotMapped und DatabaseGenerated

    Frage

  • Hallo,
    ich hole mal etwas aus um mein Problem zu Formulieren. 
    In einer MySQL Datenbank gibt es eine Tabelle, die Lagerhallen und deren Aufbau als Baumstruktur speichert.

    Halle 1
    +RaumI
      +Regal_A
        -Fach...
     +RaumII

    Mit EF Database First wurde folgende Klasse erzeugt:

        [Table("TestTreeNestedSet.Warehouse")]
        public partial class Warehouse
        {
            [Key]
            public int WarehousePK { get; set; }
    
            [Required]
            [StringLength(45)]
            public string WarehouseName { get; set; }
    
            public int? lft { get; set; }
    
            public int? rgt { get; set; }
    
            [StringLength(200)]
            public string description { get; set; }
            
            // Spalten nicht in der Datenbank vorhanden
            //[NotMapped]
            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public int Level { get; set; }
    
            //[NotMapped]
            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public int Offspring { get; set; }
        }
    }
      

    Die beiden letzten Spalten (Level und Offspring)  benötige ich nicht "physisch" in der Tabelle, die Werte lassen sich auch der lft und rgt errechnen. Sie erleichtern mir aber das aufbauen des Baumes. Irgendwo im Netz hatte ich gelesen, dass [DatabaseGenerated(DatabaseGeneratedOption.Computed)] dafür verwenden kann. Jetzt benötige ich habe auch einzelne Einträge aus der Datenbank. Wenn ich diese dann Abfrage, meckert das EF, da es Level und Offspring nicht findet. Als "Lösung"
    habe ich [NotMapped] gefunden, was auch funktioniert hat. Mit der Konsequenz, das nun der Baum nicht mehr korrekt gebaut wird und eine gewisse "Pseudorekursion" im Baum entstehen (Jeder Knoten hat den Baum nochmals komplett als Kinder). Nimmt man [NotMapped] raus passt der Baum aber halt die Einzelne Abfrage Funktioniert nicht mehr.

    Ihr Versteht mein Problem? :-)

    Die Abfrage um den Baum zu Bauen:

    public List<Warehaus> WarehausTree()
    {
    	using (DataBase_Model context = new DataBase_Model())
    	{
    		IQueryable<Warehaus> query = context.Set<Warehaus>().OrderBy(t => t.lft);                
    		
    		var result = context.Warehaus.SqlQuery("SELECT n.*,  round((n.rgt - n.lft - 1) / 2, 0) AS offspring, " +
    												" count(*) - 1 + (n.lft > 1) AS level " +											 
    												" FROM Warehaus n, " +
    												" Warehaus p " +
    												" WHERE n.lft BETWEEN p.lft AND p.rgt " +
    												" AND(p.WarehausPK != n.WarehausPK OR n.lft = 1) " +
    												" GROUP BY n.WarehausPK " +
    												" ORDER BY n.lft").ToList();
    
    		return result;
    	}
    }

    und die Abfrage für einen Eintrag:

    public Warehaus getWarehausByID(Warehaus search)
    {
    	using (DataBase_Model context = new DataBase_Model())
        {
           context.technique.Where(w => w.WarehausPK == search.WarehausPK).SingleOrDefault();
        }
    }


    Gruß Chris




    • Bearbeitet ELLoro Mittwoch, 22. März 2017 19:48
    Mittwoch, 22. März 2017 15:10

Alle Antworten

  • Hi ELLoro,

    so ganz genau hab ich dich jetzt nicht verstanden.

    Vor allem was den Baum angeht.

    Wenn ich dich richtig verstanden habe sind Level und Offspring keine Spalten in der Tabelle.

    Ich und die bei der einzelnen Abfrage bekommst du das Problem, das die Abfrage nicht funktioniert, wenn die Properties vorhanden sind und beim Select werden die Werte nicht gesetzt wenn die auf NotMapped gesetzt sind.

    Hast du es schon mit Vererbung versucht.

    My Technique : technique
    { 
    public int Level { get; set; }
    public int Offspring { get; set; }
    }
    
    //und dann beim Select
    var result = context.Warehaus.SqlQuery<MyTechnique>("SELECT n.*, 

    MFG

    Palin


    Mittwoch, 22. März 2017 16:28
  • Hallo Palin,
    der Baum wird als NestedSet in der Datenbank gespeichert, hier die Infos dazu.

    Genau, in der Tabelle gibt es keine Spalte die Level bzw. Offspring heißt.
    Die Brauche ich nur um den Baum zu bauen und lassen sich aus lft und rgt berechnen, alles beschrieben in dem Infos-Link oben. Mit Level und Offspring lässt sich halt schöner arbeiten als "(rgt - lft)/2" auf Größer Kleiner zu vergleichen.

    Mit Vererbung habe ich es noch nicht probiert, werde ich mit gleich mal machen. 

    Im Grunde will ich die zwei Spalten nur benutzen für die um berechnete Werte zu speichern, die ich aber bei den anderen Abfragen nicht benötige.

    Edit:

    Wenn ich es mit Vererbung versuche, dann bekomme ich den Fehler, DataBase_Model enthält keine Definition für MyWarehouse und es konnte keine Erweiterungsmethode gefunden werden... 

         


    • Bearbeitet ELLoro Mittwoch, 22. März 2017 21:34
    Mittwoch, 22. März 2017 20:50
  • Poste mal bitte denn Quellcode.

    Was du vielleicht mal probieren kannst ist beim select nicht auf Warehouse zu gehen Sonden auf Database.

    context.Database.SqlQuery<BlogInfo>  

    Donnerstag, 23. März 2017 07:57