Вызов FindAll для производных классов с использованием наследования таблицы классов Castle ActiveRecord - PullRequest
1 голос
/ 03 ноября 2010

Я реализую иерархию типов, используя наследование таблиц классов. Однако у меня возникли проблемы со статическими методами, возвращающими базовый тип вместо дочернего. Я нашел способ обойти это, но это не слишком красиво. Примите следующие классы

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

звонит

Person.FindAll();

фактически возвращает Entity [] вместо Person []. Я могу обойти это, внедрив FindAll во все производные классы, но кто хочет это сделать? Мне также удалось создать базовый класс, который является производным от всех классов и реализует

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

но мне просто не нравится, как выглядит

Person.FindAll<Person>()

Есть ли способ вызвать FindAll () из производных классов и фактически получить производные классы вместо базового класса?

Ответы [ 3 ]

4 голосов
/ 04 ноября 2010

Вот как работает .net: для статических методов полиморфизма нет. Вы уже нашли пару обходных путей, другой - , а не , чтобы полагаться на эти статические методы, унаследованные от ActiveRecordBase<T>, но вместо этого использовать ActiveRecordMediator<T> напрямую.

0 голосов
/ 25 апреля 2014

Даже документация Castle.ActiveRecord использует найденный вами обходной путь.

Полный пример и некоторые другие решения см. Здесь : http://docs.castleproject.org/Default.aspx?Page=Type%20hierarchy&NS=Active%20Record

Я скопировал код на случай исчезновения сайта.

Базовый класс"Сущность"

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

Производные классы"Человек "и" Компания "

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);
    }
}
0 голосов
/ 04 ноября 2010

Может быть, вы могли бы сделать:

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

Таким образом FindAll() вернется Person[]

...