Question

J'écris une application dans laquelle nous devrons étendre une entité de base à un certain nombre d'éléments différents (par exemple, un employé, un véhicule, etc.). La conception est telle qu’il existe une table Entity et une seconde table avec des valeurs spécifiques au type, par exemple un employé aura un numéro d’identification mais un véhicule aura un numéro d’immatriculation.

J'ai hérité de l'entité de classe générée dans le contexte de données, mais je rencontre des problèmes lors de la diffusion dans mon référentiel. Quelle est la bonne façon de faire cela?

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
                                            });
            }
        }
    }

}

Puis dans mon référentiel (n'hérite de rien)

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;
    }

La conversion a échoué dans la méthode single et je récupère donc null. Je crois comprendre que vous ne pouvez pas définir d’opérateurs explicites ou implicites à partir de ou vers une classe de base? Comment puis-je obtenir que le résultat Linq de la classe de base soit converti en classe Employée héritée, tout en maintenant son état de base de données afin que je puisse soumettre les modifications?

Était-ce utile?

La solution

Avec LINQ-to-SQL, l'héritage peut fonctionner de deux manières:

  • discriminateur sur une seule table (non approprié car vos données ne sont pas homogènes)
  • classe de base / multi-table (pas que cela ne soit pas supporté dans le dbml - seulement si vous écrivez les classes manuellement)

LINQ-to-SQL ne prend pas en charge l'héritage multi-tables (c'est-à-dire un seul objet avec des données provenant de plusieurs tables). Entity Framework fait, mais est plus complexe; vous utilisez .Cast<T> et .OfType<T> dans EF pour convertir / filtrer en fonction de sous-types.

Vous voudrez peut-être regarder:

Quel est le but de la classe de base ici? Si cela ajoute un comportement, vous pouvez alors éditer le dbml pour spécifier une classe de base commune pour toutes vos entités. Si elle contient des propriétés de données , la situation devient plus complexe.

Personnellement, je ne le ferais tout simplement pas de cette façon ... Je garderais des classes séparées pour les différents types et utiliserais correctement le contexte de données, en utilisant les tables séparées par type:

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);
}

Alors, pouvez-vous préciser ce que le cAccountEntity fait ici?

Autres conseils

Merci pour la contribution, examinerez certaines des suggestions ...

L'idée derrière l'entité de compte était que, à partir de maintenant, le site doit uniquement gérer les employés, mais qu'à l'avenir, ils voudront peut-être ajouter des véhicules, etc. au système, ce système est utilisé pour attribuer des coûts à une entité. un employé est traité de la même manière qu'un véhicule.

L’idée étant qu’un employé et un véhicule doivent être traités de la même manière pour les références dans la base de données, etc., mais qu’ils auront besoin d’informations légèrement différentes à leur sujet. C’est une conception complexe uniquement parce qu’ils veulent ajouter des types supplémentaires ultérieurement, mais sans avoir besoin de mettre à niveau la base de données.

Cependant, dans mon code, je souhaite parler d’un employé et non d’un type d’entité générique (rendre le contrôleur, la vue, etc. beaucoup plus facile dans une application mvc). Comme vous ne pouvez pas fournir de transtypage défini par l'utilisateur de la base à la classe dérivée, j'ai ignoré son héritage et utilisé la solution suivante à la place. Un peu plus encombrant mais qui fonctionne ... Faites-moi savoir si quelqu'un peut voir un meilleur moyen de le faire.

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));
    }
  

Comment puis-je convertir le résultat Linq de la classe de base dans la classe Employé héritée

Ce n'est pas un résultat positif, c'est un résultat négatif.

Je pense que vous ne comprenez pas le casting ou peut-être le type d'instance par rapport au type de référence.

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

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

System.InvalidCastException: impossible de convertir l'objet de type 'Animal' en 'Zebra'.

De la même manière, vous avez une instance de Entity que vous ne pouvez pas déclasser pour utiliser une référence Employé.

Vous pouvez convertir les types, mais vous devez ensuite fournir une méthode de conversion.

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();
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top