Laden...

EF - Code First: Wie Beziehungen abbilden?

Erstellt von Akhanto vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.940 Views
A
Akhanto Themenstarter:in
28 Beiträge seit 2012
vor 10 Jahren
EF - Code First: Wie Beziehungen abbilden?

verwendetes Datenbanksystem: <SQLEXPRESS / EntityFramework>

Hallo,
ich versuche mich momentan an EF. Der erste Einstieg ist relativ leicht gefallen (die ersten CRUD Experimente usw.)
Als Spielplatz habe ich mir eine simple Rechteverwaltung gebastelt (das Modell davon).

Es beinhaltet Recht, Gruppe und Benutzer.

Das Recht hat eine ID, einen Namen und eine Kategorie.

Die Gruppe hat eine ID, einen Namen, eine andere Gruppe (vererbung) und eine ICollection, die Recht(e) beinhaltet.

Der Benutzer hat eine ID, einen Benutzernamen, ein Passwort, den LetztenLogin (DateTime), eine ICollection Gruppen und eine ICollection Rechte.


Recht: 

        public int RightId { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }


Gruppe: 

        public int GroupId { get; set; }
        public string Name { get; set; }
        public virtual Group Inherits { get; set; }
        public virtual ICollection<Right> Right { get; set; }


Benutzer: 

        public int UserId { get; set; }
        public string Username{ get; set; }
        public string Password{ get; set; }
        public DateTime LastLogin{ get; set; }
        public virtual ICollection<Group> Groups{ get; set; }
        public virtual ICollection<Right> Rights{ get; set; }

Wenn ich das so erstelle, erhalte ich das was im Anhang zu sehen ist. Mir kommt es so vor, als wäre dort die Beziehung von Groups und Rights "falsch rum". Denn ich möchte ja eigentlich beim erstellen einer Gruppe einstellen, welche Rechte sie hat und nicht beim Erstellen eines Rechts einstellen, zu welchen Gruppen es gehört.
Habe ich einen Denkfehler oder einen Fehler im Modell?

Noch eine kurze Frage nebenbei: Warum ist es eigentlich nötig, alle Properties wo andere Objekte enthalten sind, als virtual zu deklarieren? Ich habe das aus dem hier so übernommen, aber keine Erklärung gefunden.

Vielen Dank
Akhanto

16.806 Beiträge seit 2008
vor 10 Jahren

virtual definiert eine Property als Lazy Loading.
Sprich die Relation wird erst geladen, wenn sie gebraucht wird. Ohne virtual erfolgt das Laden sofort (=>langsam)
Lazy Loading ist vorzuziehen und nur bei einer tatsächlich gewollten Aktion sollte alles zB über eine Materialisierung, wie ToList() angefordert werden.

Bei der Gruppe wäre es eine Sache, dass es selten sinn macht diese ohne die Inhalte anzuzeigen. Ergo würde ich hier evtl. das virtual weglassen.
Beim User aber ist es ja oft auch der Fall, dass man nur den Benutzernamen o.ä. braucht -> ergo hier machts sinn.

Verwendest Du Code First oder Model First? Ist das der alte Designer oder das Management Studio?

~~Rein vom Code stimmt Deine Logik; jedenfalls würd ichs (wenn ich mit SQL arbeiten würde) ähnlich machen.~~Siehe M@tuk

PS: Passwörter speichert man nicht im Klartext.
Bitte bitte mit Hashes salzen (Salt (cryptography))

A
Akhanto Themenstarter:in
28 Beiträge seit 2012
vor 10 Jahren

Ich mache Code First und habe mangels Erfahrung erwartet, dass man das aus dem Post erschließen kann, sry.

Das Modell ist wie gesagt erstmal nur Spielwiese ohne Achten auf irgendwelche Sicherheitsregeln oder so, deshalb mache ich mir auch keine Mühe die Passwörter zu verschlüsseln und so weiter.

Ich benutze Visual Studio 2012 Ultimate, das Diagramm habe ich mir aus dem SQL Explorer erstellen lassen.

Dass die Logik soweit richtig sein sollte, ist ja schonmal super, aber wo liegt dann der Fehler? Denn so wie das jetzt ist, kann das ja nicht funktionieren oder?
Mir ist aufgefallen, dass es Bei Benutzer und Recht ähnlich ist. Vom Diagramm her scheint er davon aus zu gehen, dass ein Recht einen Benutzer enthält, obwohl ein Benutzer ja eigentlich eine Liste von Rechten bekommen soll.
Irgendwo muss dort ein logischer Fehler sein, der das ganze nach links dreht..

Vielen Dank

16.806 Beiträge seit 2008
vor 10 Jahren

Ich würd auf das Diagramm nicht viel geben. Vllt überseh ichs auch: aber was geht denn nicht?
Logisch bzw. vom Code aus sehe ich jedenfalls aktuell keinen Fehler.
Siehe eins drunter.

M
402 Beiträge seit 2005
vor 10 Jahren

Hi...

so wie du die CodeFirst-Klassen aufgebaut hast ergibt sich zwischen User und Right ein 1:n Beziehung.
Du willst aber eine n:m Beziehung. Also musst du diese auch angeben.

public int RightId { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public virtual ICollection<User> { get; set; } 
public int UserId { get; set; }
public string Username{ get; set; }
public string Password{ get; set; }
public DateTime LastLogin{ get; set; }
public virtual ICollection<Group> Groups{ get; set; }
public virtual ICollection<Right> Rights{ get; set; } 

Edit:
Das Ganze natürlich auch bei Group <=> Right...

A
Akhanto Themenstarter:in
28 Beiträge seit 2012
vor 10 Jahren

Hi,
erstmal vielen Dank für die Hilfe.

Wahrscheinlich habe ich einen weiteren Denkfehler, aber ich verstehe deine Darstellung der Beziehungen nicht so ganz.

Es ist doch eigentlich so, dass

  1. ein Benutzer viele Rechte hat.

  2. ein Recht nicht direkt Benutzern zugordnet wird (oder?)

  3. eine Gruppe viele Rechte hat.

  4. Ein Recht auch nicht direkt Gruppen zugeordnet wird.

So wie das in meiner Logik aussieht, sind das doch 1:n Beziehungen oder nicht?

LG
Akhanto

M
402 Beiträge seit 2005
vor 10 Jahren

Hallo,

das passt schon, das EF arbeitet so.

Aus


class User
{
    public int UserId { get; set; }
    public string Username{ get; set; }
    public virtual ICollection<Right> Rights { get; set; }
}

class Right
{
    public int RightId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<User> { get; set; }
}


wird dann in der Datenbank (siehe Anhang)

A
Akhanto Themenstarter:in
28 Beiträge seit 2012
vor 10 Jahren

Hi,
danke für die Erklärung irgendwie gewöhnungsbedürftig, evtl stelle ich mich auch etwas doof an..

Gibt es eine kleine Übersicht, wie man bestimmte Beziehungen korrekt in EF Code abbildet? Ich kenne die GetStarted Seite von Microsoft, aber da habe ich sowas nicht gefunden. Da ich im Urlaub bin, habe ich nur gedrosseltes Handyinternet, was das suchen etwas schwer macht.
Falls da jemand was zur Hand hat, wäre das super, ansonsten suche ich mir selber was, wenn ich wieder zu Hause bin.

Vielen Dank
Akhanto

16.806 Beiträge seit 2008
vor 10 Jahren

In EF werden Beziehungen nicht anders abgebildet als sonst auch; es wird sogar vereinfacht.
Ansonsten sind 1:n und 1:1 Beziehungen identisch. n:m wird halt die Hilfstabelle "versteckt", wobei das auch nur so ist, wenn keine Beziehungs-abhängigen Eigenschaften und damit eine Zwischenklasse erforderlich ist.

Wenn man dazu noch das Mapping vollkommen selbst übernimmt, dann hat man mehr Wissen über sein eigenes Schema.
Dieses AutoMapping fande ich nie super. Hab das immer via FluentAPI selbst übernommen; da merkt man dann auch recht schnell, wenn man was vergessen oder was falsch bedacht hat.
Man muss sich halt damit beschäftigen...

A
Akhanto Themenstarter:in
28 Beiträge seit 2012
vor 10 Jahren

Danke für die Ratschläge, ich hab das jetzt soweit verstanden.

Die Probleme, die noch aufgetreten sind, werde ich in anderen Themen erfragen bzw. mich eben erstmal selber schlau machen.