Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 延迟加载-什么';什么是最好的方法?_C#_Architecture_Coding Style_Lazy Loading_Methodology - Fatal编程技术网

C# 延迟加载-什么';什么是最好的方法?

C# 延迟加载-什么';什么是最好的方法?,c#,architecture,coding-style,lazy-loading,methodology,C#,Architecture,Coding Style,Lazy Loading,Methodology,我已经看到了许多延迟加载的例子——您的选择是什么 例如,给定一个模型类: public class Person { private IList<Child> _children; public IList<Child> Children { get { if (_children == null) LoadChildren(); return _chi

我已经看到了许多延迟加载的例子——您的选择是什么

例如,给定一个模型类:

public class Person
{
    private IList<Child> _children;
    public IList<Child> Children
    {
        get {
            if (_children == null)
                LoadChildren();
            return _children;
        }
    }
}
公共类人物
{
私人儿童;
公营儿童
{
得到{
if(_children==null)
LoadChildren();
返回儿童;
}
}
}
Person类不应该知道它的子类是如何加载的。。。。还是应该?当然,它应该控制何时填充属性,还是不填充

您是否有一个将个人与其子集合耦合在一起的存储库,或者您是否会使用不同的方法,例如使用类—即使这样,我也不希望lazyload类在我的模型体系结构中变得模糊

如果首先请求一个人,然后请求其子对象(即在本例中不是延迟加载),或者以某种方式延迟加载,您将如何处理性能


所有这些都归结为个人选择吗?

我认为这正是AOP(如PostSharp)最好处理的问题。将您的延迟加载作为一个方面,然后使用它来装饰您希望延迟加载的任何属性。免责声明:没有尝试过;只是认为它应该工作。

最好的延迟加载是避免它;)线程安全是您必须立即处理的问题。我不知道有多少次我看到有8个cpu核的生产系统在使用中的每个延迟加载模式下运行8次延迟加载。至少在服务器启动时,所有服务器核心都倾向于在相同的位置结束

如果可以的话,让DI框架为您构建它。如果你不能,我还是喜欢显式结构。所以所有的AOP魔法都不需要我来解决,只需要在类外进行显式构造。不要将它放在person类中,只需创建一个以正确方式构造对象的服务


引入或多或少透明地完成这些事情的“神奇”层似乎是一个不错的主意,但我还没有遇到没有不可预见和有问题的结果的实现。

我谈到了一个用于实现延迟加载的解决方案

您可以使用我在这里谈到的
延迟
类:


还有一个链接指向更详细的博客文章…

您可以使用该模式以及。这将使您能够在Person类没有明确了解如何加载子类的情况下进行延迟加载。

我刚刚问了一个相关的问题,但它在不变性和线程安全性方面更为重要。很多好的答案和评论。您可能会发现它很有用。

下面是一个使用代理模式实现延迟加载的示例

将与其他模型一起使用的Person类。子项标记为虚拟,因此可以在PersonProxy类中重写它

public class Person {
    public int Id;
    public virtual IList<Child> Children { get; set; }
}

当然,如果您不想直接调用PersonRepository,您可以让PersonProxy接收PersonRepository的接口并通过服务访问它。

谢谢您的时间,你能详细介绍一下使用DI框架和显式构造吗?我想他是说让Person类在自己的初始化过程中显式地创建子类(大概是LoadChildren())会让人对_children的状态产生怀疑。还有依赖注入,这里有很多线程在注释中比我更好。而且,你失去了查询的原子性。通常情况下,最有效的总体策略是为子记录发出一个带有(外部?)连接的查询,并在一个事务中获取所有内容,而不是将其分散到多个数据库子点击中。@Le Dorfier-同意性能问题。然而,当一个对象可能有太多的子关系而无法保证一次加载所有内容时,就会出现一个临界点。在这种情况下你会怎么做?我也想知道在“太多的孩子关系”的情况下该怎么做谢谢你的时间,但这不只是另一种依赖吗?我对这个方法很感兴趣。问题-这是一个以牺牲全局优化为代价的局部优化的好例子。
public class PersonRepository {
    public Person FindById(int id) {
        // Notice we are creating PersonProxy and not Person
        Person person = new PersonProxy();

        // Set person properties based on data from the database

        return person;
    }

    public IList<Child> GetChildrenForPerson(int personId) {
        // Return your list of children from the database
    }
}
public class PersonProxy : Person {
    private PersonRepository _personRepository = new PersonRepository();

    public override IList<Child> Children {
        get {
            if (base.Children == null)
                base.Children = _personRepository.GetChildrenForPerson(this.Id);

            return base.Children;
        }
        set { base.Children = value; }
    }
}
Person person = new PersonRepository().FindById(1);
Console.WriteLine(person.Children.Count);