2017-06-21 81 views
1

我無法通過實體框架/ ASP身份保存實體。它似乎是添加所有添加的重複項。在模型之間複製數據並保存沒有在Entity Framework中複製自己的實體的數據

我嘗試過使用TeamMember.DrivingLicence = null的DrivingLicenceModel的分離圖形,然後使用分離圖形查看是否有新的或舊的DrivingLicenceCategories,但因爲DrivingLicence鏈接回TeamMember而導致TeamMember。 DrivingLicenceId爲空,因爲它無法鏈接回TeamMember。

我試過手動添加EntityState到DrivingLicence和DrivingLicenceCategories,但是當我這樣做時,它抱怨說它不能保存具有相同主鍵的兩個實體。

我認爲這是因爲他們的方式我複製的實體,但我後很多看我畫了一個空白。

如果有無論如何從TeamMemberRequestModel複製到TeamMemberModel,然後保存沒有孩子試圖創建自己的克隆副本?

模型

public class TeamMemberModel : IdentityUser 
{ 
    public virtual DrivingLicenceModel DrivingLicence { get; set; } 

    public void ShallowCopy(TeamMemberRequestModel src) 
    { 
     this.DateOfBirth = src.DateOfBirth; 

     if (src.DrivingLicence != null) 
     { 
       if (this.DrivingLicence == null) 
       { 
        this.DrivingLicence = new DrivingLicenceModel(src.DrivingLicence); 
       } 
       else 
       { 
        this.DrivingLicence.ShallowCopy(src.DrivingLicence); 
       } 
     } 
    } 

    public TeamMemberModel() { } 
} 

public class DrivingLicenceModel 
{ 
    [Key] 
    public int Id { get; set; } 

    [ForeignKey("TeamMember")] 
    public string TeamMemberId { get; set; } 

    [JsonIgnore] 
    public TeamMemberModel TeamMember { get; set; } 

    public virtual List<DrivingLicenceCategoryModel> DrivingLicenceCategories { get; set; } 

    public DrivingLicenceModel() { } 

    public DrivingLicenceModel(DrivingLicenceModel src) 
    { 
     this.ShallowCopy(src); 
    } 

    public void ShallowCopy(DrivingLicenceModel src) 
    { 
     this.Id = src.Id; 
     this.IsFullLicence = src.IsFullLicence; 
     this.IssueDate = src.IssueDate; 
     this.ExpiryDate = src.ExpiryDate; 
     this.IssuingAuthority = src.IssuingAuthority; 
     this.LicenceNumber = src.LicenceNumber; 
     this.DrivingLicenceCategories = src.DrivingLicenceCategories; 
     this.DrivingLicencePoints = src.DrivingLicencePoints; 
    } 
} 

public class DrivingLicenceCategoryModel 
{ 
    [Key] 
    public int Id { get; set; } 

    [ForeignKey("DrivingLicence")] 
    public int DrivingLicenceId { get; set; } 

    [JsonIgnore] 
    public DrivingLicenceModel DrivingLicence { get; set; } 
} 

public class TeamMemberRequestModel 
{ 
    public string Id { get; set; } 

    public virtual DrivingLicenceModel DrivingLicence { get; set; } 
} 

語境

public class TIERDBContext : IdentityDbContext<TeamMemberModel, RoleModel, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> 
{ 
    public TIERDBContext() : base("SARDBConnection") { } 

    public DbSet<DrivingLicenceModel> DrivingLicences { get; set; } 
    public DbSet<DrivingLicenceCategoryModel> DrivingLicenceCategories { get; set; } 
} 

控制器

public async Task<IHttpActionResult> Put(string id, TeamMemberRequestModel teamMember) 
{ 
     TeamMemberModel CurrentTeamMember = await this.TIERUserManager.FindByIdAsync(id); 

     CurrentTeamMember.ShallowCopy(teamMember); 

     await this.TIERUserManager.UpdateAsync(CurrentTeamMember); 
} 

回答

0

你必須創建克隆財產的來龍去脈類 。

在上下文關係中,您可以使用克隆方法來退出通過參數發送的實體,這會複製您傳遞的任何實體。對不起,我的英語

希望你幫忙

0

經過很長時間的工作,在這個。我已經回答了。處理這個問題的最好方法是簡單地處理它,就是將所有實體添加或附加到樹中。

控制器現在附加所有的孩子,除非他們的ID爲0,因此新的並使用add來代替。然後我使用這個非常有用的擴展,我在這裏找到http://yassershaikh.com/c-exceptby-extension-method/來比較列表以查看列表中添加和刪除的實體。雖然我不需要添加的部分,因爲我使用add()時該實體已經被標記爲添加狀態,但它不會造成傷害,我希望稍後通過添加和刪除狀態更改來使用它。

控制器

public async Task<IHttpActionResult> Put(string id, TeamMemberRequestModel teamMember) 
{ 
    TIERDBContext IdentityContext = (TIERDBContext)this.TIERUserManager.UserStore().Context; 

    foreach (DrivingLicenceCategoryModel DrivingLicenceCategory in teamMember.DrivingLicence.DrivingLicenceCategories) 
    { 
     if (DrivingLicenceCategory.Id == 0) 
     { 
      IdentityContext.DrivingLicenceCategories.Add(DrivingLicenceCategory); 
     } 
     else 
     { 
      IdentityContext.DrivingLicenceCategories.Attach(DrivingLicenceCategory); 
     } 
    } 

    foreach (DrivingLicencePointModel DrivingLicencePoint in teamMember.DrivingLicence.DrivingLicencePoints) 
    { 
     if (DrivingLicencePoint.Id == 0) 
     { 
      IdentityContext.DrivingLicencePoints.Add(DrivingLicencePoint); 
     } 
     else 
     { 
      IdentityContext.DrivingLicencePoints.Attach(DrivingLicencePoint); 
     } 
    } 

    this.DetectAddedOrRemoveAndSetEntityState(CurrentTeamMember.DrivingLicence.DrivingLicenceCategories.AsQueryable(),teamMember.DrivingLicence.DrivingLicenceCategories, IdentityContext); 

    this.DetectAddedOrRemoveAndSetEntityState(CurrentTeamMember.DrivingLicence.DrivingLicencePoints.AsQueryable(),teamMember.DrivingLicence.DrivingLicencePoints, IdentityContext); 

    CurrentTeamMember.ShallowCopy(teamMember); 

    await this.TIERUserManager.UpdateAsync(CurrentTeamMember); 
} 

然後我使用一個通用的使用ExceptBy摸出添加什麼,並從老隊員模式向新的團隊成員模型中刪除。

protected void DetectAddedOrRemoveAndSetEntityState<T>(IQueryable<T> old, List<T> current, TIERDBContext context) where T : class, IHasIntID 
    { 
     List<T> OldList = old.ToList(); 
     List<T> Added = current.ExceptBy(OldList, x => x.Id).ToList(); 
     List<T> Deleted = OldList.ExceptBy(current, x => x.Id).ToList(); 

     Added.ForEach(x => context.Entry(x).State = EntityState.Added); 
     Deleted.ForEach(x => context.Entry(x).State = EntityState.Deleted); 
    } 

它的作品,但它是偉大的。它需要兩個數據庫查詢,獲取原始數據和更新。我想不出有什麼更好的辦法來做到這一點。

相關問題