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