【问题标题】:Error in Xml Creation from as per Database tables : .Net Core 3.1 Memory Leak根据数据库表创建 Xml 时出错:.Net Core 3.1 内存泄漏
【发布时间】:2020-06-18 14:49:54
【问题描述】:

我正在设置一个获取 Xml 数据的方法,其数据是从数据库表中获取的。上述功能一直有效,直到 .Net Core2.1 项目更新为 .Net Core 3.1.1。 下面的代码显示了错误。

Template.cs

 orderTemplate =
                  (from ordt in _context.OrderTemplates
                   where ordt.Id == orderTempId // int orderTempId=1;
                   select new XElement("OrderTemplate",
                          new XElement("OrderTemplateId", ordt.Id),
                          new XElement("OrderTemplateName", ordt.Name),
                          new XElement("OrderTemplateDescription", ordt.Description)));

例外

Client projection contains reference to constant expression of 'System.Xml.Linq.XName'. 
This could potentially cause memory leak. Consider assigning this constant to local variable 
and using the variable in the query instead. See https://go.microsoft.com/fwlink/?linkid=2103067 for more information.

XML 数据格式:(预期输出)

<OrderTemplate>
  <OrderTemplateId>1</OrderTemplateId>
  <OrderTemplateName>BBCSeat</OrderTemplateName>
  <OrderTemplateDescription>Boeing Business Class Seat</OrderTemplateDescription>
</OrderTemplate>

Template.cs(重新编辑)

 orderTemplate =
                  (from ordt in _context.OrderTemplates
                   where ordt.Id == orderTemplateId
                  select new {
                  _OrderTemplate = ordt,
                 _OperationTemplates =(from ot in _context.OrderTemplates                                                
                                       join opt in _context.OperationTemplates 
                                     on ot.Id equals opt.OrderTemplateId into ps1                                               
                                    from opt in ps1.DefaultIfEmpty()
                                    join asm in _context.AssemblyUnits
                                    on opt.AssemblyUnitId equals asm.Id into ps5
                                   from asm in ps5.DefaultIfEmpty()
                                    where ot.Id == ordt.Id
                                      orderby opt.OrderBy ascending
                                      select new
                                                {
                                                    _OperationTemplate =  opt,
                                                    _Assembly =  asm,
})}).AsEnumerable();

已经知道这是一个重复的问题,但是我在这里做错了什么编码。请指导我。

【问题讨论】:

  • @jdweng 已经通过..这可能是错误:不再在客户端上评估 LINQ 查询并检查此github.com/dotnet/efcore/issues/12795。不知道对错?
  • 我同意这是根本原因,但不一定是实际原因。我认为模型可能需要更新。该错误似乎暗示 orderTempId 应该是一个参数: where ordt.Id == orderTempId。因此,如果查询现在是一个存储过程(在服务器而非客户端上运行),则该变量应该是一个参数。
  • 像这样来自 Api 的 ordetTempId 的实现,通过表 OrderTemp,基于该表的 id,采取行动表等等..
  • API 与 Core 3.0+ 兼容吗?

标签: c# xml entity-framework asp.net-core-2.1 asp.net-core-3.1


【解决方案1】:

只需在将实体投影到 XML 之前选择它们。无论如何,这就是 EF Core 2.1 所做的。

 var orderTemplates =_context.OrderTemplates.Where(ordt=> ordt.Id == orderTempId).AsEnumerable();

 var orderTemplate =
                  (from ordt in orderTemplates 
                   select new XElement("OrderTemplate",
                          new XElement("OrderTemplateId", ordt.Id),
                          new XElement("OrderTemplateName", ordt.Name),
                          new XElement("OrderTemplateDescription", ordt.Description))).ToList();

从概念上讲,第一行代码构建查询,将其转换为 SQL,运行 SQL 查询并返回可以使用结果的 IEnumerable。

第二行将查询结果枚举为orderTemplate 对象,并将它们投影到XElements 中,并将它们复制到一个List 中。

【讨论】:

  • 如果有n级怎么办?
  • 完全一样的逻辑。您只需将AsEnumerable() 放在where 之后即可控制服务器端和客户端评估之间的边界。
  • 感谢@David Browne - Microsoft,您介意解释一下或提供任何支持链接吗?
猜你喜欢
  • 2012-03-22
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 2011-09-27
  • 2015-06-23
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多