0

問題:如何在DTO中加載DTO?

我很新的EF和LINQ,所以請多多包涵。

我想創建一個使用數據庫第一種方法的EF6模型。簡而言之,我有兩個數據庫表tblUsertblMilkMan,它們在UserID列上有一個外鍵關係。

爲了避免循環引用和塑造實體數據,我爲這兩個模型創建了DTO類。

我發的MilkManDTO類包含一個對UserDTO實例的引用(這可能是愚蠢的,如果是這樣,請引導我以正確的方式)。我的目標是能夠加載一個milkmen和相關的用戶數據

無論如何,在我的API調用中,當我嘗試通過ID加載MilkMan時,我不知道如何加載相關的UserDTO。我在網上找到了關於如何加載相關實體但沒有相關DTO的例子。

DB模式: ER Diagram

型號:

送牛奶模型及DTO:

namespace MilkMan.Models 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class tblMilkMan 
    { 
     public int RecordID { get; set; } 
     public int UserID { get; set; } 
     public bool IsMyTurn { get; set; } 
     public int RoundRobinOrder { get; set; } 

     public virtual tblUser tblUser { get; set; } 
    } 

    public class MilkManDTO 
    { 
     public int RecordID { get; set; } 
     public int UserID { get; set; } 
     public bool IsMyTurn { get; set; } 
     public int RoundRobinOrder { get; set; } 

     public virtual UserDTO User { get; set; } 
    } 
} 

用戶模型和DTO:

public partial class tblUser 
    { 
     public tblUser() 
     { 
      this.tblMilkMen = new HashSet<tblMilkMan>(); 
     } 

     public int UserID { get; set; } 
     public string LogonName { get; set; }   
     public string Password { get; set; }   
     public int PasswordExpiresAfter { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     : 
     // more fields 
     : 
     public virtual ICollection<tblMilkMan> tblMilkMen { get; set; } 
    } 

    public class UserDTO 
    { 
     public int UserID { get; set; }  
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
    } 

的Web API控制器的方法:

// GET api/MilkMan/5 
     [ResponseType(typeof(MilkManDTO))] 
     public async Task<IHttpActionResult> GettblMilkMan(int id) 
     { 
      //tblMilkMan tblmilkman = await db.tblMilkMen.FindAsync(id); 

      MilkManDTO milkMan = await db.tblMilkMen.Select(b => new MilkManDTO() 
      { 
       RecordID = b.RecordID, 
       UserID = b.UserID, 
       IsMyTurn = b.IsMyTurn, 
       RoundRobinOrder = b.RoundRobinOrder, 
       User = //???? Error// 

      }).SingleOrDefaultAsync(b => b.RecordID == id); 


      if (milkMan == null) 
      { 
       return NotFound(); 
      } 

      return Ok(milkMan); 
     } 

回答

0

可以嵌套一個new UserDTO並使用相同的初始化列表技術。

 MilkManDTO milkMan = await db.tblMilkMen.Select(b => new MilkManDTO() 
     { 
      RecordID = b.RecordID, 
      UserID = b.UserID, 
      IsMyTurn = b.IsMyTurn, 
      RoundRobinOrder = b.RoundRobinOrder, 
      User = new UserDTO { 
       UserID = b.User.UserID, 
       FirstName = b.User.FirstName, 
       LastName = b.User.LastName, 
      } 

     }).SingleOrDefaultAsync(b => b.RecordID == id); 

此代碼可以扔b.User.UserID一個空引用異常,如果沒有相關聯的用戶,因此可以User爲空。您需要使用??合併,三元(b.User == null ? "DefaultFirstName" : b.User.FirstName)或忽略整個參考User = (b.User == null ? (UserDTO)null : new UserDTO { ... })來解決此問題。 null使這種事情變得有趣。