3

我有一个应用程序,其对象类型继承自包含应用程序对象大部分属性的基类。所有对象类型都存储在数据库的一张表中。“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()

我的问题是他们对这种类型的处理有更好的实现吗?

4

5 回答 5

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

将阅读器传递给对象的构造函数,这样它就可以完全填充自己,这种类型的代码不属于工厂。

于 2008-11-18T23:57:54.723 回答
5

我想我会为此倾向于使用对象关系映射器。NHibernate是现有的、免费的、成熟的 .NET 平台 ORM 解决方案的一个示例。

于 2008-11-18T23:49:48.563 回答
0

LINQ to SQL 可能是一个合法的选择。但是,它不能很好地与未正确使用主键和外键约束的数据库一起使用。它将根据表生成类。

于 2008-11-18T23:55:34.027 回答
0

感谢所有反馈,但我不想实现第三方工具或新语言,因为我现在没有时间学习它。

@乔纳森霍拉德:

我的对象模块当前设计如下:

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 继承的所有类?

于 2008-11-19T00:12:46.770 回答
0

You could store the fully-qualified type name in your database, and then construct it with Activator.GetInstance. This would get rid of the ugly switch statement, but would call the type's constructor instead of a factory method. Will that do what you want?

于 2008-11-19T00:45:41.163 回答