簡體   English   中英

System.AccessViolationException WebAPI2 實體框架 6

[英]System.AccessViolationException WebAPI2 Entity Framework 6

希望有人可以幫助我找到一個非常隱秘的問題。 我有一個在 .NET Framework 4.7.2 上使用 Web API 2 和 Entity Framework 6 的項目。 該項目多年來一直運行良好,我們最近決定在我們的項目中加入幾個額外的數據庫。 事實證明,EF6 不支持不同模型中名稱相似的類。 他們是一些 hacky 解決方法,自定義工具名稱間距和其他類似的東西。 或者,MS 和其他一些 SO 帖子建議遷移到 .NET Core 和 Core EF。 嘗試遷移,但事實證明它更像是移植/重寫,因為許多 EF6 功能已棄用 EF Core。 因為它是我們保釋並決定完全重新接近。 我們回滾了代碼並解決了幾個細微的問題,除了在我們發布代碼之前發現的一個類/API 調用外,一切似乎都在工作。

    [CustomAuthorize(Roles = "admin, sales, parts")]
    [Route("api/Customer/Get")]
    [HttpPost]
    public MERP.Customer GetCustomerProfile([FromBody] Models.Generic.GuidValue _input)
    {
        MARQERPEntities ent = new MARQERPEntities();
        var cst = ent.Customers.FirstOrDefault(w => w.ID == _input.ID);
        return cst;
    }

單步執行代碼, cst變量填充數據庫對象並執行返回步驟。 但是,有效負載永遠不會到達客戶端。 如果我打開任務管理器,IIS Express Worker Process 會不斷攪動,直到所有內存都被消耗完並返回以下錯誤。 我有其他使用相同代碼模式的 API 端點,它們工作正常。

未知模塊中發生類型為“System.AccessViolationException”的未處理異常。 嘗試讀取或寫入受保護的內存。 這通常表明其他內存已損壞。

我不知道如何在這里進行。 我已經吹走了 EDMX 並重新開始,我已經刪除並重新添加了 Customer 類。 其他數據庫實體已被刪除。 我已經將我們當前的packages.config與之前的 EF Core Change Set 進行了比較,它們是相同的。

這是packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net472" />
  <package id="jQuery" version="3.1.1" targetFramework="net472" />
  <package id="Microsoft.AspNet.Cors" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.4" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net472" />
  <package id="Microsoft.AspNetCore.WebUtilities" version="2.0.2" targetFramework="net472" />
  <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.0.0" targetFramework="net472" />
  <package id="Microsoft.Extensions.Logging" version="2.0.2" targetFramework="net472" />
  <package id="Microsoft.Extensions.Logging.Abstractions" version="2.0.2" targetFramework="net472" />
  <package id="Microsoft.Extensions.Options" version="2.0.2" targetFramework="net472" />
  <package id="Microsoft.Extensions.Primitives" version="2.0.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Protocols" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Protocols.WsFederation" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Tokens.Saml" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Xml" version="5.5.0" targetFramework="net472" />
  <package id="Microsoft.Net.Http.Headers" version="2.0.2" targetFramework="net472" />
  <package id="Microsoft.Owin" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.ActiveDirectory" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.Jwt" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Owin.Security.OAuth" version="4.0.1" targetFramework="net472" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
  <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net472" />
  <package id="Owin" version="1.0" targetFramework="net472" />
  <package id="PuppeteerSharp" version="1.12.0" targetFramework="net472" />
  <package id="PuppeteerSharp.AspNetFramework" version="1.12.0" targetFramework="net472" />
  <package id="System.Buffers" version="4.4.0" targetFramework="net472" />
  <package id="System.IdentityModel.Tokens.Jwt" version="5.5.0" targetFramework="net472" />
  <package id="System.IO" version="4.3.0" targetFramework="net472" />
  <package id="System.Net.Http" version="4.3.3" targetFramework="net472" />
  <package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
  <package id="System.Runtime" version="4.3.0" targetFramework="net472" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
  <package id="System.Text.Encodings.Web" version="4.4.0" targetFramework="net472" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
</packages>

需要消除的幾件事:

DbContext 不會在這樣的調用中被處理。

MARQERPEntities ent = new MARQERPEntities();
var cst = ent.Customers.FirstOrDefault(w => w.ID == _input.ID);
return cst;

應該:

using (MARQERPEntities ent = new MARQERPEntities())
{
    var cst = ent.Customers.FirstOrDefault(w => w.ID == _input.ID);
    return cst;
}

接下來,根據此MERP.Customer在屬性和通過導航屬性的關系方面的外觀,我強烈建議為 API 聲明 DTO 以返回而不是發送實體。 EF 為實體構建代理以促進諸如延遲加載之類的事情,序列化程序將選擇這些代理並將其轉換為具體類。 當序列化程序接觸虛擬成員時,它們將觸發延遲加載,這既是性能問題,也可能導致異常。 (如循環引用)這些異常可能會被 Web API 執行異常所掩蓋。

看看為包含消費者期望的客戶字段的 DTO 聲明一個 POCO C# 對象,並使用Select或 Automapper 的ProjectTo填充它,而不是發送客戶。

public CustomerDTO GetCustomerProfile([FromBody] Models.Generic.GuidValue _input)

    using (MARQERPEntities ent = new MARQERPEntities())
    {
        var cst = ent.Customers
            .Where(w => w.ID == _input.ID);
            .ProjectTo<CustomerDTO>(config)
            .SingleOrDefault();
        return cst;
    }
}

其中configMapperConfiguration實例,其中包含有關將 Customer 映射到 CustomerDTO(以及任何相關實體到 DTO 映射)的任何詳細信息進行初始化

如果您必須發送整個客戶圖,請確保所有必需的導航引用都是預先加載的 /w Include組合暫時關閉延遲加載:

using (MARQERPEntities ent = new MARQERPEntities())
{
    ent.Configuration.LazyLoadingEnabled = false;
    var cst = ent.Customers
        .Include(w => w.Address) // as an example, Eager fetch anything you want included.
        .FirstOrDefault(w => w.ID == _input.ID);
    return cst;
}

當這第一次發生時,我不確定行為是如何或何時開始的,或者原因是什么。 EDMX 是從數據庫生成的,有時 EDMX 會損壞,最簡單的解決方法是完全清除 EDMX 並重新加載它。 發生這種情況時,延遲加載已啟用設置將恢復為 true。

在此處輸入圖片說明

您必須在選項卡中打開 EDMX 並轉到屬性,您將看到 ConceptualEntityModel 屬性。 如果您轉到解決方案資源管理器,選擇 EDMX 並轉到屬性,您將獲得 EDMX 的文件屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM