【问题标题】:Better way to build objects in C#在 C# 中构建对象的更好方法
【发布时间】:2010-09-22 23:16:11
【问题描述】:

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

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

【问题讨论】:

    标签: c# data-access-layer


    【解决方案1】:

    如果您不想切换到生成 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);
        }        
    

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

    【讨论】:

    • 我对将阅读器传递给 ctor 持怀疑态度 - 但不介意从 IDataReader 字段到重新选择参数的通用映射器。否则,我宁愿 IDataReader 的东西留在 DAL 或 ObjectFactory 中。
    • 不是真的需要,但是标准化所有的键。
    【解决方案2】:

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

    【讨论】:

    • 不知道为什么我对这个答案投了反对票,这不是合法的做法吗?
    • 不知道你为什么这样做。我赞成这两个答案。在这种情况下,他似乎已经滚动了他的对象,所以没有什么可以做的。
    • 确实,哦,好吧...您的反射方法是一种优雅的选择。来自我的 +1
    【解决方案3】:

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

    @乔纳森霍拉德:

    我的对象模块目前是这样设计的:

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

    【讨论】:

      【解决方案4】:

      您可以将完全限定的类型名称存储在数据库中,然后使用Activator.GetInstance 构造它。这将摆脱丑陋的 switch 语句,但会调用类型的构造函数而不是工厂方法。这会做你想做的事吗?

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多