【问题标题】:Object composition references -- bidirectional?对象组合引用——双向?
【发布时间】:2011-03-16 18:03:34
【问题描述】:

假设你有一个类对象:

public class Class
{
    IList<Student> students;
}

你有一个学生对象:

public class Student
{
    private Class class;
}

从数据库加载这些对象时,加载关联的最佳方式是什么?

加载课程时,您将获得一个空的学生列表。如果您先加载学生,则在加载类之前,您将对类对象有一个空引用。

【问题讨论】:

  • 这不是取决于您的业务规则吗?
  • 好吧,我的域逻辑假设引用已经存在于两个方向(即它不关心它是如何被初始化的)。
  • 那你为什么不能同时加载它们呢?每当您的客户第一次请求时,加载学生列表和班级对象。

标签: c# .net


【解决方案1】:

从数据库加载这些对象时,加载关联的最佳方式是什么?

如果您使用的是 ORM,只需让延迟加载功能处理它即可。请注意 select n + 1 问题。

如果您不使用 ORM,请开始使用 ORM。

【讨论】:

    【解决方案2】:

    这是我一直在努力解决的问题之一。 (到目前为止)我想出的最优雅的方法是简单地为为我处理所有这些的对象创建属性。

    归根结底,这取决于您在什么情况下使用这些课程。例如,在成绩簿应用程序中,您会深入研究课程并进入学生记录。另一方面,如果您正在做一个班级注册申请,您会将学生添加到班级,然后从学生向下钻取到他们注册的班级。

    由于我们没有您正在讨论的应用程序的实际范围,所以让我们推出通用样式,好吗?这是一个类的经典类。 (啊,这很有趣。)然而,同样的想法也适用于 Student 类。

    public class Class
    {
        IList<Student> _students;
        public IList<Student> Students
        {
            get
            {
                if(_students == null)
                {
                    _students = new IList<Student>();
                    PopulateStudents(); // just for simplicity
                }
            }
            // no need for a setter usually... Use Students.Add(Student s)
        }
    }
    

    这允许您为这个特定班级按需加载学生。假设这是用于 Web 开发,如果您的应用程序正在查看有关课程的信息,但现在不需要学生列表,为什么要从数据库中提取它? PopulateStudents() 可以任意复杂。至少你会把数据库调用放在那里,但是在那里放一些缓存也不是一个坏主意。

    如果操作正确,您就不必担心加载对象的顺序。当你想要/需要它们时,它们都会被加载,并且不需要你在消费代码中考虑。当你打电话时

    Class c = new Class(id); // You do need a class to get its students...
    IList<Students> studentList = c.Students;
    

    您真的不知道您的数据是否已经被提取,或者仍然需要被提取,或者什么 - 您关心什么?让班级自己处理棘手的细节。

    当然,您需要考虑一些问题。例如,“新”类(换句话说,数据库中还没有的类)呢?然而,通过一些彻底的编程,最终结果是相同的。

    【讨论】:

    • 感谢您的周到回答。这绝对看起来是个好主意——但是,我有点厌倦了将逻辑从课堂本身的数据访问层填充学生。不过,我想我会使用这种方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 2012-06-15
    • 2012-03-07
    • 1970-01-01
    相关资源
    最近更新 更多