在我的WebAPI Web应用程序中,我向表添加了一个varbinary(max)字段,并向POCO(BatchCharge)添加了byte []字段。这个实体有一个子实体(Charge)。
Visual Studio 2013,实体框架6,SQL Server 2014。
数据模型如下:
public class BatchCharge
{
public int ID { get; set; }
public byte[] FileData { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}
public class Charge
{
public int ID { get; set; }
public DateTime CreatedUTC { get; set; }
public decimal Amount { get; set; }
public virtual BatchCharge BatchCharge { get; set; }
}
映射是在Charge实体(子实体)上完成的,如下所示:
public class ChargeMap : EntityTypeConfiguration<Charge>
{
public ChargeMap()
{
// Primary Key
HasKey(t => t.ID);
// Table and Column Mappings
ToTable("Charge");
Property(t => t.ID).HasColumnName("ID");
Property(t => t.ID).IsRequired();
Property(t => t.CreatedUTC).HasColumnName("CreatedUTC");
Property(t => t.CreatedUTC).IsRequired();
Property(t => t.Amount).HasColumnName("Amount");
Property(t => t.Amount).IsRequired();
HasRequired(t => t.BatchCharge)
.WithMany(t => t.Charges)
.HasForeignKey(d => d.BatchChargeID);
}
}
使用以下方法检索BatchCharges列表时:
[ActionName("GetBatchCharges")]
[HttpGet]
[Route("api/charges/batches")]
[Authorize(Roles = "Administrator")]
public HttpResponseMessage GetBatchCharges(int skip = 0,
int take = 25,
int statusFilter = 0)
{
try
{
var batchCharges = _centralDb.BatchCharges.AsQueryable();
if (statusFilter > 0)
{
batchCharges = batchCharges.Where(bc => bc.StatusID == statusFilter);
}
// Page and list.
var allBatchCharges = batchCharges.OrderByDescending(c => c.CreatedUTC);
var totalCount = allBatchCharges.Count();
var thePage = allBatchCharges.Skip(take * skip).Take(take).ToList();
// Transform and return.
var result = new
{
TotalCount = totalCount,
CurrentPage = skip,
BatchCharges = thePage.Select(c => MapperFactory.Mapper.Map<BatchCharge, BatchChargeDTO>(c)).ToList()
};
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
const string message = "Exception getting batch charges.";
Logger.Error(ex, message);
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new HttpError(message));
}
}
我收到一个OutOfMemoryException。当我在上面的行中中断并尝试查看查询结果时,我看到的是错误“由于内存不足异常而禁用了功能评估”。请参见下面的屏幕截图。
这告诉我EF6内部发生了内存不足异常。
我已经看到了有关如何增加进程内存的几个相关答案。我不认为这是问题所在。测试数据包括BatchCharge(父)表中的六行,最大文件大小为27 KB!
该文件是包含子实体(收费)信息的CSV文件。使用此模型,我可以使用文件数据上传和保存BatchCharges,没有问题。我还成功地将其用于每个BatchCharge的少量Charges(子实体)。
当我上传带有600个Charges的BatchCharge作为孩子时,问题就开始了。如前所述,这不是文件大小的问题,因为文件大小为27KB。
如果这里有一个循环引用,它应该在我拥有的许多其他类似配置的关系中发生。还是字节数组字段与父/子关系一起产生了问题?如果是这样,怎么办?
编辑: 当我用try / catch块包围代码,并在调试器中逐步运行它时,它不会在代码的任何地方引发异常!但是,到达浏览器的响应包括一个标准的IIS未处理的异常页面,并带有服务器错误,如下所示(运行代码段以查看输出):
body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;}
p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
@media screen and (max-width: 639px) {
pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
}
@media screen and (max-width: 479px) {
pre { width: 280px; }
}
<body bgcolor="white">
<span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>
<h2> <i>Exception of type 'System.OutOfMemoryException' was thrown.</i> </h2></span>
<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">
<b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
<br><br>
<b> Exception Details: </b>System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.<br><br>
<b>Source Error:</b> <br><br>
<table width=100% bgcolor="#ffffcc">
<tr>
<td>
<code>
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.</code>
</td>
</tr>
</table>
<br>
<b>Stack Trace:</b> <br><br>
<table width=100% bgcolor="#ffffcc">
<tr>
<td>
<code><pre>
[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
System.IO.MemoryStream.set_Capacity(Int32 value) +89
System.IO.MemoryStream.EnsureCapacity(Int32 value) +90
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +326
Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.ArteryFilter.Write(Byte[] buffer, Int32 offset, Int32 count) +106
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +475
System.Web.HttpResponse.FilterOutput() +154
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +247
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +117
</pre></code>
</td>
</tr>
</table>
<br>
<hr width=100% size=1 color=silver>
<b>Version Information:</b> Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.7.3056.0
</font>
</body>
答案 0 :(得分:3)
由于@IvanStoev,在DTO中发现了问题:它们引用了EF属性(如下所述),这会导致较大数据集的内存不足异常。
public class BatchChargeDTO
{
public int ID { get; set; }
public byte[] FileData { get; set; }
// Problem is here: type should be ChargeDTO!!
public ICollection<Charge> Charges { get; set; }
}
public class ChargeDTO
{
public int ID { get; set; }
public DateTime CreatedUTC { get; set; }
public decimal Amount { get; set; }
public int? BatchChargeID { get; set; }
// Problem is here: type should be BatchChargeDTO!!
public BatchCharge BatchCharge { get; set; }
}