Frage

Ich schreibe eine Anwendung, wo wir brauchen eine grundlegende Einheit in eine Reihe von verschiedenen Dingen (zB Mitarbeiter, Fahrzeug usw.) zu erweitern. Das Design ist so, dass es eine Entity-Tabelle und eine zweite Tabelle mit typspezifischen Werten zB Mitarbeiter werden eine ID-Nummer haben, aber ein Fahrzeug wird eine Registrierungsnummer hat.

Ich habe aus der Klasse Einheit im Kontextdaten erzeugt geerbt, aber mit dem Gießen in meinem Repository Problem habe. Was ist der richtige Weg, dies zu tun?

public class cAccountEmployee : cAccountEntity
{
    public string id_number
    {
        get
        {
            try
            {
                return this.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }

}

Dann in meinem Repository (nicht erbt nichts)

public IEnumerable<cAccountEmployee> All(int accountholder_id)
    {
        return db.cAccountEntities.Where(e => e.accountholder_id == accountholder_id).OrderBy(a => a.name).Cast<cAccountEmployee>();
    }

    public cAccountEmployee Single(int id)
    {
        return db.cAccountEntities.Single(a => a.id == id) as cAccountEmployee;
    }

Die Besetzung nicht in den einzelnen Verfahren und damit komme ich wieder null. Es ist mein Verständnis nicht explizit oder implizit Betreiber von oder zu einer Basisklasse definieren kann? Wie kann ich die Basisklasse Linq Ergebnis an die geerbte Klasse Employee zu werfen, während nach wie vor seinen db Zustand beibehalten wird, so kann ich Änderungen einreichen?

War es hilfreich?

Lösung

Mit LINQ-to-SQL, gibt es zwei Möglichkeiten Vererbung arbeiten kann:

  • Diskriminator über eine einzelne Tabelle (nicht geeignet, da die Daten nicht homogen)
  • base-Klasse / Multi-Table (nicht, dass dies nicht im dbml unterstützt - nur, wenn Sie die Klassen manuell schreiben)

LINQ-to-SQL nicht unterstützt Multi-Table-Erbe (das heißt ein einzelnes Objekt mit Daten aus mehreren Tabellen). Entity Framework tut, ist aber komplexer; Sie verwenden .Cast<T> und .OfType<T> in EF zu werfen / Filter auf Basis von Untertypen.

Sie könnten wollen, betrachten

Was ist der Zweck der Basisklasse hier? Wenn es Verhalten fügt hinzu, dann können Sie die dbml bearbeiten, um eine gemeinsame Basis-Klasse für alle Einheiten angeben. Wenn es hat Dateneigenschaften dann wird es schwieriger.

Ich persönlich würde es einfach nicht auf diese Weise tun ... Ich würde für die verschiedenen Arten getrennte Klassen hält, und den Daten-Kontext korrekt verwenden, die separaten Tabellen pro Typen mit:

public IEnumerable<Employee> All(int accountholder_id)
{
    return db.Employees.Where(e => e.accountholder_id == accountholder_id)
        .OrderBy(a => a.name);
}

public Employee Single(int id)
{
    return db.Employees.Single(a => a.id == id);
}

So - können Sie klären, was der cAccountEntity tut hier

Andere Tipps

Danke für den Input, werden einige der Vorschläge durchsehen ...

Die Idee hinter Konto Entität war, dass die Website ab jetzt nur Mitarbeiter verarbeiten muss aber in Zukunft wollen sie können Fahrzeuge usw. zu dem System hinzuzufügen, wird das System verwendet Kosten einer Einheit zuzuweisen, so dass für diesen Zweck Mitarbeiter sind das gleiche wie ein Fahrzeug behandelt.

Die Idee ist, dass ein Mitarbeiter und ein Fahrzeug Notwendigkeit, ihm das gleiche für die Referenzierung in der db usw. behandelt werden aber über ihnen etwas andere Informationen benötigen. Es ist ein komplexes Design nur, weil sie später zusätzliche Typen hinzufügen wollen, aber ohne dass die DB aktualisieren ...

In meinem Code aber ich möchte über einen Mitarbeiter nicht über eine generische Entitätstyp (make-Controller, Ansicht usw. viel leichter in einem MVC-app) sprechen. Da Sie nicht eine benutzerdefinierte Gießen von Basisklasse abgeleitet liefern kann ich inheritting es übersprungen und verwendet stattdessen die folgende Lösung. Etwas umständlich, aber funktioniert ... Lassen Sie mich wissen, wenn jemand einen besseren Weg, dies zu tun sehen.

public class cAccountEmployee
{
    private cAccountEntity entity;

    public int id
    {
        get
        {
            return this.entity.id;
        }
        set
        {
            this.entity.id = value;
        }
    }

    public string name
    {
        get
        {
            return this.entity.name;
        }
        set
        {
            this.entity.name = value;
        }
    }

    public int accountholder_id
    {
        get
        {
            return this.entity.accountholder_id;
        }
        set
        {
            this.entity.accountholder_id = value;
        }
    }

    public System.Data.Linq.EntitySet<cAccountEntityValue> cAccountEntityValues
    {
        get
        {
            return this.entity.cAccountEntityValues;
        }
    }

    public cAccountHolder cAccountHolder
    {
        get
        {
            return this.entity.cAccountHolder;
        }
    }

    public cAccountEmployee()
    {
        this.entity = new cAccountEntity();
    }

    public cAccountEmployee(cAccountEntity entity)
    {
        this.entity = entity;
    }

    public string id_number
    {
        get
        {
            try
            {
                return this.entity.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.entity.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.entity.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this.entity,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }
}

//In the repository
public cAccountEmployee Single(int id)
    {
        return new cAccountEmployee(db.cAccountEntities.Single(a => a.id == id));
    }
  

Wie kann ich die Basisklasse Linq Ergebnis zu erhalten, um die geerbte Klasse Employee aufschütten

Es ist kein upcast, es ist ein niedergeschlagene.

Ich glaube, Sie verstehen nicht, Gießen oder möglicherweise -. Instanztyp vs Referenztyp

public class Animal { }
public class Zebra : Animal { }

public class Zoo
{
    public void ShowZebraCast()
    {
        Animal a = new Animal();
        Zebra z = (Zebra)a;
    }
}

System.InvalidCastException. Konnte nicht das Objekt vom Typ 'Animal' werfen 'Zebra' eingeben

In der gleichen Art und Weise haben Sie eine Instanz von Entity, die Ihnen nicht niedergeschlagenen eine Employee Referenz gegen ihn zu verwenden.

Sie können die Typen konvertieren, aber dann müssen Sie ein Konvertierungsverfahren liefern.

public partial class Animal { }
public class Zebra : Animal { }
//in another file
public partial class Animal{
  public Zebra ToZebra(){
    return new Zebra() { //set Zebra properties here.
    };
  }
}


public class Zoo
{
    public void ShowZebraConvert()
    {
        Animal a = new Animal();
        Zebra z = a.ToZebra();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top