循环 IEnumerable<T> 抛出不支持的异常

Posted

技术标签:

【中文标题】循环 IEnumerable<T> 抛出不支持的异常【英文标题】:Loop over IEnumerable<T> throw an Not Supported exception 【发布时间】:2020-06-22 03:55:44 【问题描述】:

我需要一个只返回列表中的一些项目的查询,并且我需要将这些项目放入数据库中。

这是返回 IEnumerable 的 linq 查询:

 IEnumerable<VerificaParcheggio> targheOK = from c in verifica
                                                     join d in db.Net_Veicoli_Targhe
                                                     on c.Targa equals d.Targa
                                                     join tt in db.BT_Titoli_Targhe
                                                     on new  idVeicolo = d.IDVeicolo, DataTroncata = DbFunctions.TruncateTime(c.DataUscita)  equals new  idVeicolo = tt.IDVeicolo, DataTroncata = DbFunctions.TruncateTime(tt.Scadenza) 
                                                     join td in db.BT_Titoli_Dettagli
                                                     on new  tt.IDTitolo, c.IDParcheggio  equals new  td.IDTitolo, IDParcheggio = td.IDGCPark == null ? 0 : td.IDGCPark.Value 
                                                     where tt.Attiva
                                                     && ((td.Validita == 1 && c.DataUscita.Hour <= 13) || (td.Validita == 2 && c.DataUscita.Hour > 13))
                                                     select new VerificaParcheggio()  IDParcheggio = c.IDParcheggio, DataUscita = c.DataUscita, Targa = c.Targa ;

然后我想遍历这个 IEnumerable,因为我需要从数据库中获取一些数据,这些数据需要放入我要填充的表中:

using (var transaction = db.Database.BeginTransaction())
                

                    try
                    

                        foreach (VerificaParcheggio v in targheOK) /*THIS LINE THROW THE EXCEPTION*/
                        
                            BT_Verifica_Parcheggi verificaPa = (from c in db.BT_Verifica_Parcheggi
                                                               where c.idParcheggio == v.IDParcheggio &&
                                                               c.Targa == v.Targa &&
                                                               c.DataUscita == v.DataUscita
                                                               select c).FirstOrDefault();

                            decimal idVeicolo = (from c in db.Net_Veicoli_Targhe
                                             where c.Targa == v.Targa
                                             orderby c.DataOraInserimento descending
                                             select c.IDVeicolo).FirstOrDefault();

                            DatiComproprietarioVeicolo datiComproprietarioVeicolo = TitolariVeicoli.GetProprietarioPrincipaleVeicolo(idVeicolo);

                            decimal idAnagrafica = (from c in db.Net_Soggetti_Anagrafica
                                                where c.CodiceFiscale == datiComproprietarioVeicolo.codFiscale
                                                select c.IDAnagrafica).FirstOrDefault();

                            BT_Verifica_Parcheggi_KO parcheggi = new BT_Verifica_Parcheggi_KO
                            
                                IDVerifica = verificaPa.IDVerifica,
                                idAnagrafica = idAnagrafica,
                                Esito = false
                            ;
                            db.BT_Verifica_Parcheggi_KO.Add(parcheggi);
                        

                        db.SaveChanges();
                        transaction.Commit();
catch (Exception ex)
                    
                        transaction.Rollback();
                        throw (ex);
                    
                

当我到达 foreach 语句时,程序开始迭代,大约 50 秒后它捕获到一个异常

"此函数只能从 LINQ to Entities 调用。"

为什么会产生这个错误?

编辑:捕获异常时报行

非常感谢。

【问题讨论】:

将 Try/Catch 放在 foreach 内部而不是外部,这样您就可以继续通过异常。 哈哈,好问题 @MichaelRandall 我在代码报告中添加了一条注释,报告捕获的地方 @jdweng 我在这里需要异常,因为我正在使用 try 和 catch 管理事务 请从您的代码中删除过多的缩进。帮助人们轻松阅读您的问题(最终帮助您自己)。 【参考方案1】:

看起来您只准备了 LINQ 查询,但尚未在数据库上执行,因此您的 IEnumerable 集合上没有数据。

您可能希望在循环之前执行targheOK.AsEnumerable() 方法调用,以便将记录转储到内存中,并且您可以遍历行。

【讨论】:

不应该在您第一次开始枚举集合时自动执行此操作吗?我认为明确的 AsEnumerable 在这里不会有任何区别。我认为这也不能解释具体的例外情况。 这会有所不同,因为执行是延迟执行,像AsEnumerableToList这样的调用将加载内存中的所有数据

以上是关于循环 IEnumerable<T> 抛出不支持的异常的主要内容,如果未能解决你的问题,请参考以下文章

将 IEnumerable<Ienumerable<T>> 转换为 Dictionary<key,IEnumerable<T>>

如何将两个 IEnumerable<T> 连接成一个新的 IEnumerable<T>?

无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”

如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>

c# IEnumerable<T>

IEnumerable<T>是啥意思?