簡體   English   中英

實體框架在使用 AutoMapper 后分離虛擬對象

[英]Entity Framework detached virtual object after using AutoMapper

我已經建立了一個 MVC 環境,我在其中使用實體框架實體,將其映射到 DTO 以供用戶修改,然后將 DTO 映射回 EF 實體。

我的EF課程如下:

public class Person
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int AddressId { get; set; }
    public virtual StreetAddress Address { get; set; }
    /*More stuff here*/
}
//For the purpose of this example lets assume that addresses cannot be changed, they are read-only
public class StreetAddress
{
    [Key]
    public int Id { get; set; }
    public string StreetName { get; set; }
    /*More stuff here*/
}

我的 DTO 是:

public class PersonDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int AddressId { get; set; }
    public StreetAddress Address { get; set; }
    /*More stuff here*/
}

從這里我將 Person 映射到 PersonDTO 並再次返回:

Person person = /*retrieve from database*/;
PersonDTO dto = Mapper.Map<PersonDTO>(person);

// send dto to user, user updates name, user sends dto back
// the address object is the same, but it might have been converted to JSON or something like that during transport

Person person = Mapper.Map<Person>(dto);

所以我現在有一個 Person 准備好保存到數據庫中。 StreetAddress 對象仍然具有相同的信息,但是現在 EF 將 Address 視為分離的。 我不能使用context.Attach(Address)因為上下文已經有一個帶有相同 Key 的 StreetAddress,並且嘗試這樣做會導致拋出異常。

如果我選擇忽略分離的地址並將這個新人添加到我的數據庫中,EF 會將地址視為一個全新的對象並將其插入數據庫,從而導致數據庫中的地址行重復,詳細信息相同,新 ID。

我當前的解決方案是將 Address 對象替換為已經附加到上下文的對象:

var tracked = context.ChangeTracker.Entries<Address>();
person.Address = tracked.Where(x => x.Entity.Id == person.AddressId).Select(e => e.Entity).FirstOrDefault();

有一個更好的方法嗎? 也許是一種告訴 EF 如果有一個地址的人的方法,其中地址 ID 已經在數據庫中,則不需要插入它?

一種方法是使您的FK AddressId在人與PersonDTO。

另一種是將實體狀態設置為已修改: context.Entry(person.Address).State = EntityState.Modified; 如圖所示這里

暫無
暫無

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

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