2008-11-18 4 views
3

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

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

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

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

+0

В том же духе: Linq to SQL возможно .... – 2008-11-18 23:54:29

+0

Не знаете, почему я зашел за этот ответ, его законный ход действий - это не так? – 2008-11-19 00:06:31

0

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

6

Этот подход заключается в том, что вы не хотите переключаться на код, генерирующий 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); 
    }   

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

0

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

Hollard @ Джонатан:

Мой объектный модуль предназначен ток, как это:

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

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