虚拟代理如何工作?

发布于 2024-11-16 03:31:17 字数 845 浏览 6 评论 0原文

我在理解虚拟代理方面遇到了一些麻烦。我阅读了大量的文章,并花了几个小时试图找到好的信息,但我还没有找到全面的东西。因此,我将在这里提出一个通用请求,以获取更好的信息(发布在这里或只是一个链接)。我还将在下面添加一些细节,以更好地解释我到底想要什么。

我有几个对象,它们之间有很多引用。为了简洁起见,我将拥有一个具有基本父子关系的对象(节点)。当我从数据库中取出这个对象时,我想实现延迟加载。据我所知,虚拟代理本质上将通过引用接口(INode)并根据需要拉取数据成员来为我处理所有延迟加载。 [注意:我实际上没有 INode 类,但是当我将 virtual 关键字放在我的数据成员上时,似乎确实使用了代理]

当我将类中的数据成员设为虚拟时,它似乎创建了一个代理。这是虚拟代理吗?这些实现了延迟加载吗?

我搜索了有关 virtual 关键字的信息,但我能找到的唯一文档是在方法上使用它,该方法用于继承,以便派生类可以重写该函数,这与我想要的无关(我认为) 。

这是我当前的 Node.cs

[DataContract(IsReference=true)]
public partial class Node
{
  [DataMember]
  public long ID { get; private set; }
  [DataMember]
  public virtual Node Parent { get; set; }
  [DataMember]
  public virtual ICollection<Node> Children { get; set; }
}

基本上在这一点上我非常困惑,只需要一些关于这个主题的指导,甚至是我可以查找的在线资源,因为我发现的所有资源都没有什么帮助。

提前致谢。

I am having some trouble wrapping my head around virtual proxies. I have read tons of articles and spent several hours trying to find good information, but I have yet to find something comprehensive. So I will make a generic request here for better information (either posted here or just a link). I will also add some detail below to better explain what exactly it is I want.

I have several objects and there are many references between them. For the sake of brevity I will have one object (Node) with a basic parent-child relationship. When I pull this object out of the database, I would like to implement lazy-loading. From what I have read, a virtual proxy will essentially handle all the lazy-loading for me by referencing the interface (INode) and pulling data members as needed. [Note: I do not actually have an INode class, but when I put the virtual keyword on my data members, a proxy did seem to be used]

When I make data members in my classes virtual, it seems to make a proxy. Is this a virtual proxy? Do these implement lazy-loading?

I searched for information about the virtual keyword, but the only documentation I could find was to use it on methods, which is used for inheritance so that derived classes can override the function, which has nothing to do with what I want (I think).

This is my current Node.cs

[DataContract(IsReference=true)]
public partial class Node
{
  [DataMember]
  public long ID { get; private set; }
  [DataMember]
  public virtual Node Parent { get; set; }
  [DataMember]
  public virtual ICollection<Node> Children { get; set; }
}

Basically at this point I am very confused and just need some guidance on this topic, or even an online resource that I can look to, since all the ones I have found have been less than helpful.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染火枫林 2024-11-23 03:31:17

“虚拟”代理和延迟加载是与 ORM 工具相关的东西。代理实际上不是虚拟的,而是动态的,并且遵循 GoF 定义的真实代理模式。

动态代理是 ORM 工具在运行时创建的类(它没有在任何地方定义为代码文件)。它源自您的实体并覆盖导航属性。因此,它们必须是虚拟的才能使代理工作。代理在私有字段或任何更复杂的结构中保存导航属性的状态,如果第一次访问该属性,它会看到该状态已卸载并触发从数据库加载并将状态更改为已加载。

无论如何,我不确定这如何指代 WCF,因为最佳实践不是使用 WCF 延迟加载。为什么?

  • 如果在服务器端使用延迟加载,序列化将始终从数据库整个对象图中提取,因为序列化将访问每个导航属性并触发延迟加载,但随后它将开始序列化延迟加载的实体并访问其所有导航属性等。
  • 客户端上的延迟加载侧面是一些模糊的东西。首先,客户端的延迟加载完全取决于您 - 您必须实现它。使用服务时,您应该始终遵循 SOA 原则之一:服务边界是明确的。这意味着您的对象的用户应该始终知道他正在执行远程调用而不是本地调用。分布式计算的主要目标是减少网络往返,因此您应该使用急切加载并在可能的情况下在一次往返中传输所有需要的数据,而不是使用延迟加载。这同样适用于从数据库加载 - 在有意义时使用延迟加载,因为数据库的往返操作可能是昂贵的操作。

"Virtual" proxy and lazy loading is something related to ORM tools. The proxy actually is not virtual it is dynamic and it follows real Proxy pattern defined by GoF.

Dynamic proxy is class created by ORM tool at runtime (it is not defined as a code file anywhere). It derives from your entity and it overrides navigation properties. Because of that they must be virtual to make a proxy work. The proxy holds a state of navigation property in private field or any more complex structure and if the property is accessed first time it sees that the state is unloaded and triggers loading from database and change the state to loaded.

Anyway I'm not sure how this refers to WCF because best practice is not using lazy loading with WCF. Why?

  • If you use lazy loading on server side serialization will always pull from database whole object graph because serialization will access every navigation property and triggers lazy loading but it will then start serializing lazy loaded entities and access all their navigation properties, etc.
  • Lazy loading on client side is something blured. First of all lazy loading on client side is completely up to you - you must implement it. When using services you should always follow one of SOA tenets: Service boundary is explicit. It means that user of your object should always know that he is doing remote call instead of local call. Main target in distributed computing is reducing network roundtrips so you should use eager loading and transfer all needed data in a single roundtrip if possible instead of using deferred loading. The same is applicable for loading from database - use lazy loading when it make sense because roundrips to database can be costly operations.
抽个烟儿 2024-11-23 03:31:17

我认为您需要一些私人领域来支持您的虚拟财产。在这些虚拟属性的获取覆盖中,您检查私有字段以查看其当前是否有效(是否已从数据库获取,是否是最新的等) - 如果不是,则获取或重新获取它。我不认为事情会比这更复杂。

基类:

private Node _Parent;
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch.
}

覆盖:

public override Node Parent {
    get {
        if (_Parent==null) // or out of date, dirty etc
            Do_db_get_of_parent();
        return _Parent;
    }
}

I think you want some private fields backing your virtual properites. In the get overrides of these virtual properties you check the private field to see if its currently valid (has it been got already from db, is it upto date etc) - if not then fetch or refetch it. I don't see it has to been anymore complicated than that.

Base class:

private Node _Parent;
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch.
}

Override:

public override Node Parent {
    get {
        if (_Parent==null) // or out of date, dirty etc
            Do_db_get_of_parent();
        return _Parent;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文