简体   繁体   English

如何在DTO中加载DTO?

[英]How to load DTO Within DTOs?


PROBLEM: 问题:

I am very new to EF and to LINQ, so please bear with me. 我对EF和LINQ还是陌生的,所以请多多包涵。

I am trying to create a EF6 model using the database first approach. 我正在尝试使用数据库优先方法创建EF6模型。 Simply speaking, I have 2 database tables tblUser and tblMilkMan which have a foreign key relationship on the UserID column. 简单来说,我有2个数据库表tblUsertblMilkMan ,它们在UserID列上具有外键关系。

To avoid cyclic references and to shape the entity data I have created DTO classes for both the models. 为了避免循环引用并塑造实体数据,我为两个模型都创建了DTO类。

I made the MilkManDTO class contain a reference to a UserDTO instance.(This is probably stupid, if so, please guide me to the right way).My aim is to be able to load a milkmen and the related User data 我使MilkManDTO类包含对UserDTO实例的引用(这可能是愚蠢的,如果这样的话,请以正确的方式指导我)我的目标是能够加载送牛奶者和相关的User数据

Anyway in my API call, when I try to load a MilkMan by ID, I do not know how to load the related UserDTO . 无论如何,在我的API调用中,当我尝试通过ID加载MilkMan时,我不知道如何加载相关的UserDTO I found examples online on how to load related Entities but not related DTOs. 我在网上找到了有关如何加载相关实体而不加载相关DTO的示例。

DB Schema: 数据库架构: ER图

Models: 楷模:

MilkMan Model and 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; }
    }
}

User Model and DTO: 用户模型和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 Controller Method: 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);
        }

You can nest a new UserDTO and use the same initialization list technique. 您可以嵌套一个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);

This code may throw a null reference exception on b.User.UserID if there is not associated User and thus User could be null. 如果没有关联的User,则此代码可能会在b.User.UserID上引发null引用异常,因此User可能为null。 You would need to deal with this with either a ?? 您需要使用??来处理此问题。 coalesce, ternary (b.User == null ? "DefaultFirstName" : b.User.FirstName) or omit the entire reference User = (b.User == null ? (UserDTO)null : new UserDTO { ... }) . 合并,三元(b.User == null ? "DefaultFirstName" : b.User.FirstName)或忽略整个引用User = (b.User == null ? (UserDTO)null : new UserDTO { ... }) null's make this kind of thing fun. null让这种事情变得有趣。

With C# 6 we have null reference operator .? 在C#6中,我们有空引用运算符.? that makes this much more succinct. 这使得它更加简洁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM