3 Stimmen

Warum generieren meine Fluent NHibernate SubClass-Mappings redundante Spalten?

Ich habe die folgenden Entitäten

public abstract class Card
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }

    public virtual Product Product { get; set; }
    public virtual Sprint Sprint { get; set; }
}
public class Story:Card
{
    public virtual double Points { get; set; }
    public virtual int Priority { get; set; }
}
public class Product
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    public virtual IList Stories { get; private set; }

    public Product()
    {
         Stories = new List();
    }
}

Und die folgenden Zuordnungen

public class CardMap:ClassMap
{
    public CardMap()
    {
        Id(c => c.Id)
            .Index("Card_Id");

        Map(c => c.Name)
            .Length(50)
            .Not.Nullable();
        Map(c => c.Description)
            .Length(1024)
            .Not.Nullable();

        References(c=>c.Product)
            .Not.Nullable();

        References(c=>c.Sprint)
            .Nullable();

    }
}
public class StoryMap : SubclassMap
{
    public StoryMap()
    {
        Map(s => s.Points);
        Map(s => s.Priority);

    }
}
public class ProductMap:ClassMap
{
    public ProductMap()
    {
        Id(p => p.Id)
            .Index("Product_Id");

        Map(p => p.Name)
            .Length(50)
            .Not.Nullable();

        HasMany(p => p.Stories)
            .Inverse();
    }

Wenn ich mein Schema generiere, werden die Tabellen wie folgt erstellt

Card
---------
Id
Name
Description
Product_id
Sprint_id

Story
------------
Card_id
Points
Priority
Product_id
Sprint_id

Was ich erwartet hätte, wäre gewesen, die Spalten Product_id und Sprint_id NUR in der Card-Tabelle zu sehen, nicht in der Story-Tabelle.

Was mache ich falsch oder missverstehe ich?

1voto

fostandy Punkte 4032

NB: Nur für das NH2-Projekt getestet

Nun, du wirst wahrscheinlich auf eine Tür kauen wollen, sobald du das liest, aber der TLDR-Grund ist, dass die Product_id und Spring_id Spalten in deiner Story-Tabelle nicht redundant sind - sie existieren für die HasMany(x => x.Stories)-Beziehungen in deinem SpringMap und ProductMap. Sie haben zufälligerweise die gleiche Namenskonvention wie die CardMap References(x => x.Product und References(x => x.Sprint).

Überprüfe dies selbst, indem du ProductMap.cs:24-25 und SprintMap.cs:22 auskommentierst und neu baust.

Wenn das oben Gesagte keinen Sinn ergibt, lass es mich wissen und ich werde versuchen, es genauer zu erklären.

Also sollte es so funktionieren wie es ist. Wenn du die Spalten klarer definieren möchtest, könntest du die Spaltennamen explizit wie folgt festlegen:

ProductMap.cs
        HasMany(p => p.Stories)
            .KeyColumn("ProductOwner_id")
            .Inverse();

SprintMap.cs
        HasMany(s => s.Stories)
            .KeyColumn("SprintOwner_id")
            ;

CardMap.cs
        References(c=>c.Product)
            .Column("Product_id")
            .Not.Nullable();

        References(c=>c.Sprint)
            .Column("Sprint_id")
            .Nullable();

Hier gehe ich davon aus, dass die 1:N-Beziehungen zwischen einer Story und einem Produkt/Sprint einen "Besitzer" darstellen. Du möchtest es semantisch entsprechend umbenennen.

Noch etwas. Ich hätte gedacht, dass die letzten Änderungen (die Änderungen an CardMap.cs) unnötig wären - aber aus irgendeinem Grund scheinen sie nötig zu sein, sonst wird die Sprint_id-Spalte zu SprintOwner_id. Ich habe keine Ahnung, warum das passiert - ich würde vermuten, dass dies eine Art bidirektionale Beziehungsinferenz seitens Fluent/NHibernate ist, die schiefgelaufen ist, aber darauf würde ich sehr wenig setzen.

0voto

gillyb Punkte 8377

Ich sehe, dass die Story-Entität von der von Ihnen erstellten Card-Entität erbt, aber Sie wissen nicht, warum Sie Product_Id und Sprint_Id Eigenschaften im Story Tabellenschema haben, da sie virtuelle Eigenschaften in der Card-Klasse sind.

Ich vermute, dass dies passiert, weil in NHibernate alle Eigenschaften virtuell sein müssen, aber nur am Anfang. Sie bleiben nicht wirklich virtuell. Das NHibernate-Framework überschreibt sie, und wahrscheinlich passiert Ihnen das deshalb.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X