2010-11-03 3 views
1

J'implémente une hiérarchie de types en utilisant l'héritage de table de classes. Cependant, j'ai des problèmes avec les méthodes statiques qui retournent le type de base au lieu du type enfant. J'ai trouvé un moyen de contourner cela mais ce n'est pas trop joli. Prenez les classes suivantesAppel de FindAll sur des classes dérivées en utilisant l'héritage de table de classes Castle ActiveRecord

public class Entity : ActiveRecordBase<Entity> { } 
public class Person : Entity {} 

appelant

Person.FindAll(); 

retourne en fait une entité [] au lieu d'une personne []. Je peux contourner cela en implémentant FindAll dans toutes les classes dérivées, mais qui veut faire ça? Je suis également en mesure de créer une classe de base que toutes les classes dérivent et mettre en œuvre

public R[] FindAll<R>() {} 

mais je n'aime pas le look de

Person.FindAll<Person>() 

Est-il possible de pouvoir appeler FindAll() des classes dérivées et obtient réellement les classes dérivées au lieu de la classe de base?

Répondre

4

Voilà comment fonctionne .net: il n'y a pas de polymorphisme pour les méthodes statiques. Vous avez déjà trouvé un couple de solutions de contournement, un autre est pas pour s'appuyer sur ces méthodes statiques héritées de ActiveRecordBase<T>, mais à la place utiliser ActiveRecordMediator<T> directement.

0

Peut-être que vous pourriez faire:

public class Entity<T> : ActiveRecordBase<T> { } 
public class Person : Entity<Person> {} 

De cette façon FindAll() retournerait Person[]

+0

Le problème est que vous ne pouvez pas la carte 'entité ' comme c'est une classe générique ouverte. –

+0

J'ai déjà utilisé ce modèle, où Entity doit être utilisé pour contenir des valeurs communes (ex: id) et des méthodes, et comme un ancêtre commun à toutes les entités. Je ne vois pas pourquoi vous voudriez le cartographier. – gcores

+0

@gcores: vous pouvez donc placer les propriétés de Entity dans une classe séparée. –

0

Même la documentation de Castle.ActiveRecord utilise la solution de contournement que vous avez trouvé.

Voir ici un exemple complet et d'autres solutions: http://docs.castleproject.org/Default.aspx?Page=Type%20hierarchy&NS=Active%20Record

Je copié le code dans le cas où le site disparaît.

Classe de base "Entité"

using Castle.ActiveRecord; 

[ActiveRecord("entity"), JoinedBase] 
public class Entity : ActiveRecordBase 
{ 
    private int id; 
    private string name; 
    private string type; 

    public Entity() 
    { 
    } 

    [PrimaryKey] 
    private int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    [Property] 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    [Property] 
    public string Type 
    { 
     get { return type; } 
     set { type = value; } 
    } 

    public static void DeleteAll() 
    { 
     DeleteAll(typeof(Entity)); 
    } 

    public static Entity[] FindAll() 
    { 
     return (Entity[]) FindAll(typeof(Entity)); 
    } 

    public static Entity Find(int id) 
    { 
     return (Entity) FindByPrimaryKey(typeof(Entity), id); 
    } 
} 

Les classes dérivées "Personne" et "Société"

using Castle.ActiveRecord; 

[ActiveRecord("entitycompany")] 
public class CompanyEntity : Entity 
{ 
    private byte company_type; 
    private int comp_id; 

    [JoinedKey("comp_id")] 
    public int CompId 
    { 
     get { return comp_id; } 
     set { comp_id = value; } 
    } 

    [Property("company_type")] 
    public byte CompanyType 
    { 
     get { return company_type; } 
     set { company_type = value; } 
    } 

    public new static void DeleteAll() 
    { 
     DeleteAll(typeof(CompanyEntity)); 
    } 

    public new static CompanyEntity[] FindAll() 
    { 
     return (CompanyEntity[]) FindAll(typeof(CompanyEntity)); 
    } 

    public new static CompanyEntity Find(int id) 
    { 
     return (CompanyEntity) FindByPrimaryKey(typeof(CompanyEntity), id); 
    } 
} 

[ActiveRecord("entityperson")] 
public class PersonEntity : Entity 
{ 
    private int person_id; 

    [JoinedKey] 
    public int Person_Id 
    { 
     get { return person_id; } 
     set { person_id = value; } 
    } 

    public new static void DeleteAll() 
    { 
     DeleteAll(typeof(PersonEntity)); 
    } 

    public new static PersonEntity[] FindAll() 
    { 
     return (PersonEntity[]) FindAll(typeof(PersonEntity)); 
    } 

    public new static PersonEntity Find(int id) 
    { 
     return (PersonEntity) FindByPrimaryKey(typeof(PersonEntity), id); 
    } 
} 
Questions connexes