簡體   English   中英

實體更新時,實體框架不會更新外鍵

[英]Entity Framework not updating foreign key when entity updates

我正在將Entity Framework與Web API 2一起使用。我有一個Boat實體,其屬性如名稱,價格等。當由Put發送到Web api控制器時,這些簡單的屬性可以很好地更新。 船實體還與稱為BoatType的實體具有多對一關系。 船只類型為“游艇”,“機動游艇”等。

在控制器中更新船實體時,數據庫中船類型的外鍵不會更新。 我是否必須以某種方式手動更新子實體值,或者是否有辦法讓EF自動執行此操作?

這是發送到Web API的示例PUT請求:

{
  "$id":"1",
  "Images":[],
  "BoatType": {
    "$id":"3",
    "Boat":[],
    "Id":1,
    "DateCreated":"2015-09-15T13:14:39.077",
    "Name":"Yacht"
  },
  "Id":2,
  "Name":"Schooner",
  "Description":"A harmless schooner",
  "DateCreated":"2015-09-15T17:59:37.8",
  "Price":65000
}

這是Web API中的更新功能:

[ResponseType(typeof(void))]
public async Task<IHttpActionResult> Put(int id, Boat boat)
{
    if (id != boat.Id)
    {
        return BadRequest();
    }

    _db.Entry(boat).State = EntityState.Modified;

    try
    {
        await _db.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!BoatExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    return StatusCode(HttpStatusCode.NoContent);
}

我看過類似的問題,例如實體框架代碼“第一次更新不更新外鍵” ,“ 實體框架不更新外鍵對象”“使用實體框架更新外鍵”,但是似乎沒有一個完全相同的場景(或者答案沒有幫助我了解我的問題)。

這是Boat和BoatType模型類(由EF設計器自動生成)。

public partial class Boat
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Boat()
    {
        this.Images = new HashSet<Image>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public System.DateTime DateCreated { get; set; }
    public Nullable<double> Price { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Image> Images { get; set; }
    public virtual BoatType BoatType { get; set; }
} 

public partial class BoatType
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public BoatType()
    {
        this.Boat = new HashSet<Boat>();
    }

    public int Id { get; set; }
    public System.DateTime DateCreated { get; set; }
    public string Name { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Boat> Boat { get; set; }
}

好的,我找出了問題所在。 使用SQL Server Profiler查看SQL Update語句,我發現Boat.BoatType的外鍵甚至不在其中-因此,我認為我的模型必須在某個地方搞砸了。 在設計器中創建模型時,我錯誤地將Boat和BoatType之間的關系設置為一對一。 后來我意識到了這個錯誤,並將關聯從一個(BoatType)更改為許多(Boats),但這一定是在生成數據庫之后進行的。 天哪! 關於EF處理關聯的方式,這意味着僅更改圖中的關聯類型是不夠的-那時我應該刪除/重新創建數據庫約束。

由於我只有數據庫中的測試數據,因此對我有用的是使用設計器中的“從模型生成數據庫...”選項重新創建數據庫。

一旦我讓PUT正常工作,我就不得不解決另一件事(這個問題並不是真正的話題,但是上面已經討論過,以防萬一它對某人有用)是Web API給出了錯誤“參照完整性約束發生沖突:關系的一端“ Boat.BoatTypeId”的屬性值與另一端“ Boat.BoatType.Id”的屬性值不匹配。” 使用AngularJS在客戶端上將允許用戶更改船型的選擇列表綁定到Boat.BoatType。 因此,在PUT數據中,Boat.BoatType已更新為新值,但Boat.BoatTypeId並未更改-因此出現“參照完整性”錯誤。 因此,我只是在發送PUT之前手動將Boat.BoatTypeId的值設置為Boat.BoatType.Id,並且所有工作現在都按預期進行。

暫無
暫無

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

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