Лучший способ строить объекты в C # - PullRequest
3 голосов
/ 19 ноября 2008

У меня есть приложение с моими объектными типами, которые наследуются от базового класса, который содержит большинство свойств для объектов приложения. Все типы объектов хранятся в одной таблице в базе данных. Столбец «ClassType» определяет, к какому типу объектов я приведу строку SqlDataReader.

Вот моя текущая реализация:

SqlDataReader dr = SqlServerHelper.ExecuteReader("MyStoreProc", MySqlParmas);

if(dr.HasRows)
{
    while(dr.Read())
    {
        switch(dr["ClassType"].ToString())
        {
            case "ClassA":
                //cast sqldatareader a ClassA object
                ClassA a = new ClassFactory.CreateClassA(object p1, object p2);
            case "ClassB":
                //cast sqldatareader a ClassB object
                ClassB b = new ClassFactory.CreateClassB(object p1, object p2);
        //it continues for all objects with app....
        }
    }
}

dr.Close()

У меня вопрос, является ли их лучшая реализация для этого типа обработки?

Ответы [ 5 ]

6 голосов
/ 19 ноября 2008

Этот подход, если вы не хотите переключаться на код, генерирующий ORM.

В таблицу объектов включите полное имя типа объекта.

Затем вы можете сделать что-то вроде:

    private Dictionary<String, Type> _objectTypes = new Dictionary<String, Type>();

    public ObjectFactory()
    {
        // Preload the Object Types into a dictionary so we can look them up later
        foreach (Type type in typeof(ObjectFactory).Assembly.GetTypes())
        {
            if (type.IsSubclassOf(typeof(BaseEntity)))
            {
                _objectTypes[type.Name.ToLower()] = type;
            }
        }
    }

Теперь, с предварительно загруженным преобразователем, вы можете заменить свой код на:

    string objectName = dr["ClassType"].ToString().ToLower();
    Type objectType;

    if (_objectTypes.TryGetValue(objectName, out objectType))
    {
       return (BaseEntity)Activator.CreateInstance(objectType,reader);
    }        

Передайте читателю конструктор вашего объекта, чтобы он мог полностью заполнить себя, этот тип кода не принадлежит фабрике.

5 голосов
/ 19 ноября 2008

Полагаю, для этого я бы склонялся к объектно-реляционному мапперу. NHibernate является примером существующего бесплатного зрелого решения ORM для платформы .NET.

0 голосов
/ 19 ноября 2008

Вы можете сохранить полное имя типа в вашей базе данных, а затем создать его с помощью Activator.GetInstance. Это избавило бы от уродливого оператора switch, но вызвало бы конструктор типа вместо фабричного метода. Будет ли это делать то, что вы хотите?

0 голосов
/ 19 ноября 2008

Спасибо за все отзывы, но я не хочу внедрять сторонний инструмент или новый язык, потому что у меня сейчас нет времени, чтобы выучить его прямо сейчас.

@ Джонатан Холлард:

Мой объектный модуль в настоящее время имеет следующий дизайн:

public class BaseClass
{
    public BaseClass() { }

    public object p1 { get; set;}

    public object p2 { get; set; }

    public virtual void ImplementLogic()  
    {
        //do some fun stuff....
    }
}

public class ClassA : BaseClass
{
    public ClassA { }

    public override void ImplementLogic()
    {
        //make it rain.....
    }
} 

public class ClassB : BaseClass
{
    public ClassB { }    

    public override void ImplementLogic()
    {
        //do some more fun stuff
    }
}

Как это будет работать с этой моделью?

Буду ли я бросать первый пример кода в конструктор BaseClassFactory, потому что он распознает все классы, унаследованные от BaseClass?

0 голосов
/ 19 ноября 2008

LINQ to SQL может быть допустимым вариантом. Тем не менее, он не очень хорошо работает с базами данных, которые не связаны должным образом с первичным и внешним ключами. Он будет генерировать класс на основе таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...