延迟加载 - (实体框架)底层连接意外关闭

Posted

技术标签:

【中文标题】延迟加载 - (实体框架)底层连接意外关闭【英文标题】:Lazy Loading - (Entity Framework) The Underlying Connection was Closed Unexpectedly 【发布时间】:2015-11-11 11:58:03 【问题描述】:

我正在尝试使用实体框架实现延迟加载。我会提前承认我从来没有这样做过并且正在努力。所以我尝试的一切都是基于我在这里找到的文章。基本上我现在得到底层连接意外关闭错误消息。

当我执行 WCF 跟踪时,如果您正在使用 DataContractSerializer 或将任何静态未知类型添加到已知类型列表,则表明在尝试使用 DataContractResolver 序列化参数 http://tempuri.org...Consider 时出错。

因此,我研究了 DataContractResolver,但不清楚如何实现它,还不清楚我如何知道我是否正在使用 DataContractSerializer。就像我说的那样,我是新手。

这是我当前的代码:

 public OMBCase GetOMBCaseByCaseId(long caseId)
    
        //using (AWCTSDBEntities context = new AWCTSDBEntities())
        AWCTSDBEntities context = new AWCTSDBEntities();
        //
        try
        
            context.Configuration.ProxyCreationEnabled = true;
            context.Configuration.LazyLoadingEnabled = true;
            context.Configuration.AutoDetectChangesEnabled = false;

            ((IObjectContextAdapter)context).ObjectContext.CommandTimeout = 120;
            context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

            var caseRecQuery = (from c in context.Cases
                                where (c.CaseId == caseId && c.SystemTypeCode == SystemCodes.OMB)
                                select c).OfType<OMBCase>();

            var caseRecord = caseRecQuery.Single();
            var soldierDetails = caseRecord.Soldier;
            var soldierAddress = soldierDetails.Addresses.ToList();
            foreach (var p in soldierDetails.Addresses)
            
                var soldierAddressPurpose = p.AddressPurposes;
                foreach (var ap in soldierAddressPurpose)
                
                    var purpose = ap;
                
            
            var soldierTelehone = soldierDetails.Telephones.ToList();
            var soldierEmail = soldierDetails.Emails.ToList();
            var soldierContacts = soldierDetails.Contacts.ToList();
            foreach (var ca in soldierDetails.Contacts)
            
                var contactAddress = ca.Addresses;
                foreach (var cp in contactAddress)
                
                    var contactAddressPurposes = cp.AddressPurposes;
                
            
            foreach (var ce in soldierDetails.Contacts)
            
                var contactEmails = ce.Emails;
            
            foreach (var ct in soldierDetails.Contacts)
            
                var contactTelephone = ct.Telephones;
            
            var personInterviewed = caseRecord.PersonInterviewed;
            var createdByUser = caseRecord.CreatedByUser;
            context.Dispose();
            return (caseRecord);
            //
        
        catch (NullReferenceException)
        
            context.Dispose();
            return (null);
        
        catch (Exception e)
        
            context.Dispose();
            WriteToLogFile(e);
            return (null);
            //    
        


    

如果您能提供任何关于从这里去哪里的指导,我们将不胜感激。

提前感谢您提供的任何帮助。

罗德尼

【问题讨论】:

它在哪一行抛出异常?是在你返回值之后吗? 它在返回。当我在调试器中查看代码时,我看到所有的值都回来了,而且看起来都很好。然后我返回,一切都死了。 调用 context.Dispose(); 后查看值我有一种感觉,当这种情况发生时,他们都会走出窗外。你之前的问题是类似的,这个问题是相同的吗? ***.com/questions/31703801/… 我尝试不使用具有相同结果的 dispose。老实说,我也在想同样的事情。但这似乎并没有什么不同。 调用 context.Dispose() 后的值是什么样的? 【参考方案1】:

在请求实际值之前,“延迟加载”不会填充您的任何类。这也意味着当context 超出范围(或被释放)时,查询的对象就不好了。

看起来你的程序正在这样做:

Logic logic logic; // Logic before getting case
var case = GetOMBCaseByCaseId(caseid);
Logic logic logic; // Logic performed on case

延迟加载最适合这样的场景,其中逻辑在上下文超出范围之前执行:

ProcessOMBCaseByCaseId(Int32 caseid)

    using (AWCTSDBEntities context = new AWCTSDBEntities())
    
        var caseRecQuery = (from c in context.Cases
                            where (c.CaseId == caseId && c.SystemTypeCode == SystemCodes.OMB)
                            select c).OfType<OMBCase>(); 

        Logic logic logic; // Logic performed on case
    

【讨论】:

我可能在这里表现出一点无知,​​但是这个调用在后端服务器上的 WCF 土地上已经结束了,直到它返回到前端之后才消耗它的逻辑。所以当我看到你在说什么时,我只是不清楚如何实现它。

以上是关于延迟加载 - (实体框架)底层连接意外关闭的主要内容,如果未能解决你的问题,请参考以下文章

实体框架急切加载不返回数据,延迟加载有

使用 DTO 在实体框架中延迟加载

实体框架 - 停止按需延迟加载相关实体?

C# - 实体框架代码优先,延迟加载不起作用

使用实体框架更新数据库记录(延迟加载和虚拟属性)

为啥在本机查询 Hibernate 延迟加载的子实体中?