【问题标题】:How to load DTO Within DTOs?如何在 DTO 中加载 DTO?
【发布时间】:2015-01-08 05:09:46
【问题描述】:

问题:

我对 EF 和 LINQ 还很陌生,所以请多多包涵。

我正在尝试使用数据库优先方法创建 EF6 模型。简单来说,我有 2 个数据库表 tblUsertblMilkMan,它们在 UserID 列上有外键关系。

为了避免循环引用和塑造实体数据,我为这两个模型创建了 DTO 类。

我使MilkManDTO 类包含对UserDTO 实例的引用。(这可能很愚蠢,如果是,请指导我正确的方式)。我的目标是能够加载送奶工和相关用户数据

无论如何,在我的 API 调用中,当我尝试通过 ID 加载 MilkMan 时,我不知道如何加载相关的 UserDTO。我在网上找到了有关如何加载相关实体但不加载相关 DTO 的示例。

数据库架构:

型号:

MilkMan 模型和 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);
        }

【问题讨论】:

    标签: c# linq entity-framework entity-framework-6 asp.net-web-api2


    【解决方案1】:

    您可以嵌套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 让这种事情变得有趣。

    在 C# 6 中,我们有空引用运算符 .?,这使得这更加简洁。

    【讨论】:

      猜你喜欢
      • 2019-02-26
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多