You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Entity Framework:使用实际对象在上下文内查找代理

解决方案:WCF传输实体后在接收端上下文查找对应代理

我之前在项目里处理过几乎一模一样的场景,分享下我的实操思路和方法:

首先得明确几个前提:我们通常不会直接传输EF的动态代理对象(因为序列化容易出问题),一般是先把代理转成纯POCO实体再通过WCF发送;接收端拿到POCO后,要在自己的EF上下文里找是否已有对应主键的代理对象,核心是靠主键匹配来定位。

具体实现步骤

  • 第一步:确保WCF传输的是POCO实体
    从发送端上下文拿到代理对象后,先转成POCO:

    // 假设你的实体是Order,dbContext是发送端的EF上下文
    var proxyOrder = dbContext.Orders.First(o => o.Id == orderId);
    // 转成POCO
    var pocoOrder = dbContext.Entry(proxyOrder).CurrentValues.ToObject() as Order;
    

    然后把pocoOrder通过WCF发送,避免代理序列化的兼容性问题。

  • 第二步:接收端查找已有代理
    拿到POCO实体后,有两种方式查找上下文里的代理:

    1. 优先查本地缓存+自动查库:用Find()方法
      Find()会先检查上下文的本地跟踪缓存(也就是已经加载的代理对象),找到直接返回;找不到就去数据库查询并加载:
      var receivedPocoOrder = ...; // 从WCF接收的POCO
      var existingProxy = dbContext.Orders.Find(receivedPocoOrder.Id);
      
    2. 只查本地缓存:用Local属性
      如果不想触发数据库查询,只检查已经加载到上下文内存里的实体:
      var existingProxy = dbContext.Orders.Local.FirstOrDefault(o => o.Id == receivedPocoOrder.Id);
      
  • 第三步:把接收的POCO转为代理(如果需要)
    如果查不到现有代理,想把接收的POCO附加到上下文并生成代理,只需要:

    dbContext.Orders.Attach(receivedPocoOrder);
    // 或者指定状态
    dbContext.Entry(receivedPocoOrder).State = EntityState.Unchanged;
    

    只要你的上下文开启了代理创建(默认是开启的,即dbContext.Configuration.ProxyCreationEnabled = true),EF会自动为这个POCO生成代理对象。

注意事项

  • 如果你非要直接传输代理对象,需要把WCF的序列化器换成NetDataContractSerializer(默认的DataContractSerializer不支持动态生成的代理类型),但这种方式容易有版本兼容问题,不推荐。
  • 一定要确保发送端和接收端的实体类定义完全一致(包括命名空间、属性、主键配置),否则会出现类型不匹配或者主键识别错误的问题。

内容的提问来源于stack exchange,提问作者PigSpider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:11:35