title: Is This How to Create a Data Transfer Object (DTO) with Entity Framework Core & ASP.NET Core MVC 2.2+ and 3.0
body: <p>In creating a RESTful Api with ASP.NET Core MVC 2.2 I noticed there wasn't a a DTO example like the 2014 web api example. </p>
  
  <p><a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&amp;tabs=visual-studio#routing-and-url-paths" rel="noreferrer">ASP.NET Core MVC 2.2 Rest api 2019 example</a></p>
  
  <p><a href="https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5" rel="noreferrer">ASP.NET web-api 2014 example</a></p>
  
  <p>So, I decided to create DTO's for a few of my controller verbs HTTPGet, HTTPPost and HTTPPut </p>
  
  <p>I have 2 fold questions from my final result. </p>
  
  <ol>
  <li><p>Is this the recommended way of doing it in a general sense.  Or is there something in the new Entity Framework Core that is different or better than the 2014 example that was based on Entity Framework 6 or previous?  </p></li>
  <li><p>Should one utilize the DTO design pattern in general?  Or is there something in the Entity Framework Core that is different from a DTO pattern altogether.  Specifically is there a way to take data from a database and pass it to the view/client the exact way I need it to be passed over?  </p></li>
  </ol>
  
  <p>More background to the reason for asking question part 2.  I have read about DTO's being anti-patterns and people say don't use them for one reason or another.  However, many developers implore their usage and when and why they should be used.  A personal example for me is working and Angular and React projects. Receiving data I need is a beautiful thing that I can't imagine any other the other alternative which would be to do all types of hoops and parsing to get through a monolithic object to display address and location onto the screen. </p>
  
  <p>But have times changed and is there a design pattern or another pattern that would do the exact same thing but at a lower expense and compute cost.  </p>
  
  <ol start="3">
  <li><p>For that matter is there a great compute cost to the server and dbserver for using this pattern?  </p></li>
  <li><p>Lastly, is the code below how one would expect to utilize a DTO pattern in Entity Framework Core as opposed to the EF 6 or linq to sql frameworks?  </p></li>
  </ol>
  
  <p>I have included the code changes below to illustrate my DTO creation for the TodoItem model from the below exercise. </p>
  
  <p><strong>Project(TodoApi) --> DTOs --> TodoItemDTO.cs:</strong></p>
  
  <pre><code>using System.ComponentModel;
  using System.ComponentModel.DataAnnotations;
  
  namespace TodoApi.Models
  {
      public class TodoItemDTO
      {
          [Required]
          public string Names { get; set; }
  
          [DefaultValue(false)]
          public bool IsCompletes { get; set; }
      }
  
      public class TodoItemDetailDTO
      {
          public long Id { get; set; }
  
          [Required]
          public string Names { get; set; }
  
          [DefaultValue(false)]
          public bool IsCompletes { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>Project(TodoApi) --> Controllers--> TodoController.cs:</strong></p>
  
  <pre><code>using System.Linq;
  using System.Threading.Tasks;
  using Microsoft.AspNetCore.Mvc;
  using Microsoft.EntityFrameworkCore;
  using TodoApi.Models;
  
  // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
  
  namespace TodoApi.Controllers
  {
      [Produces("application/json")]
      [Route("api/[controller]")]
      [ApiController]
      public class TodoController: ControllerBase
      {
          private readonly TodoContext _context;
  
          public TodoController(TodoContext context)
          {
              _context = context;
  
              if (_context.TodoItems.Count() == 0)
              {
                  // Create a new TodoItem if collection is empty, 
                  // which means you can't delte all TodoItems.
                  _context.TodoItems.Add(new TodoItem { Name = "Item1" });
                  _context.SaveChanges();
              }
  
              // Console.WriteLine(GetTodoItems());
          }
  
          // Get: api/Todo
          [HttpGet]
          public async Task&lt;ActionResult&lt;IQueryable&lt;TodoItem&gt;&gt;&gt; GetTodoItems()
          {
              var todoItems = await _context.TodoItems.Select(t =&gt;
                          new TodoItemDetailDTO()
                          {
                              Id = t.Id,
                              Names = t.Name,
                              IsCompletes = t.IsComplete
                          }).ToListAsync();
  
              return Ok(todoItems);
  
              // previous return statement
              //return await _context.TodoItems.ToListAsync();
          }
  
          // Get: api/Todo/5
          [HttpGet("{id}")]
          [ProducesResponseType(typeof(TodoItemDetailDTO), 201)]
          public async Task&lt;ActionResult&lt;TodoItem&gt;&gt; GetTodoItem(long id)
          {
              var todoItem = await _context.TodoItems.Select(t =&gt;
              new TodoItemDetailDTO()
              {
                  Id = t.Id,
                  Names = t.Name,
                  IsCompletes = t.IsComplete
              }).SingleOrDefaultAsync(t =&gt; t.Id == id);
  
              if (todoItem == null)
              {
                  return NotFound();
              }
  
              return Ok(todoItem);
  
              //var todoItem = await _context.TodoItems.FindAsync(id);
  
              //////if (todoItem == null)
              //{
              //    return NotFound();
              //}
  
              //return todoItem;
          }
  
          // POST: api/Todo
          /// &lt;summary&gt;
          /// Creates a TodoItem.
          /// &lt;/summary&gt;
          /// &lt;remarks&gt;
          /// Sample request:
          ///
          ///     POST /Todo
          ///     {
          ///        "id": 1,
          ///        "name": "Item1",
          ///        "isComplete": true
          ///     }
          ///
          /// &lt;/remarks&gt;
          /// &lt;param name="item"&gt;&lt;/param&gt;
          /// &lt;returns&gt;A newly created TodoItem&lt;/returns&gt;
          /// &lt;response code="201"&gt;Returns the newly created item&lt;/response&gt;
          /// &lt;response code="400"&gt;If the item is null&lt;/response&gt;            
          [HttpPost]
          [ProducesResponseType(typeof(TodoItemDTO), 201)]
          [ProducesResponseType(typeof(TodoItemDTO), 400)]
          public async Task&lt;ActionResult&lt;TodoItem&gt;&gt; PostTodoItem(TodoItem item)
          {
              _context.TodoItems.Add(item);
              await _context.SaveChangesAsync();
  
              _context.Entry(item).Property(x =&gt; x.Name);
              var dto = new TodoItemDTO()
              {
                  Names = item.Name,
                  IsCompletes = item.IsComplete
              };
  
              // didn't use because CreatedAtAction Worked
              // return CreatedAtRoute("DefaultApi", new { id = item.Id }, dto);
  
              return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, dto);
  
              // original item call for new todoitem post
              //return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, item);
          }
  
          // PUT: api/Todo/5
          [HttpPut("{id}")]
          [ProducesResponseType(typeof(TodoItemDTO), 201)]
          [ProducesResponseType(typeof(TodoItemDTO), 400)]
          public async Task&lt;IActionResult&gt; PutTodoItem(long id, TodoItem item)
          {
              if (id != item.Id)
              {
                  return BadRequest();
              }
  
              _context.Entry(item).State = EntityState.Modified;
              await _context.SaveChangesAsync();
  
              var dto = new TodoItemDTO()
              {
                  Names = item.Name,
                  IsCompletes = item.IsComplete
              };
  
              return CreatedAtAction(nameof(GetTodoItem), new { id = item.Id }, dto);
          }
  
          // DELETE: api/Todo/5
          [HttpDelete("{id}")]
          public async Task&lt;IActionResult&gt; DeleteTodoItem(long id)
          {
              var todoItem = await _context.TodoItems.FindAsync(id);
  
              if (todoItem == null)
              {
                  return NotFound();
              }
  
              _context.TodoItems.Remove(todoItem);
              await _context.SaveChangesAsync();
  
              return NoContent();
          }
      }
  }
  </code></pre>