2
\$\begingroup\$

I have an ASP.NET MVC 5 app and I map properties between model and viewmodel and vice versa.

I could use automapper to do this but since I don't need mapping rules to convince me to use it as I mostly do simple 1 to 1 mapping the performance overhead that automapper will add is not worthwhile.If I have mapping differences I'll map it manually where I reference it in my controller.

Here is my code

public class Dog
{
 public int Id { get; set; }
 public string Name { get; set; }
 public DateTime? BirthDate { get; set; }
 public int? CreatedBy{ get; set; }
 public DateTime? DateCreated { get; set; }
}
public class DogViewModel
{
 public int Id { get; set; }
 public string Name { get; set; }
 public DateTime? BirthDate { get; set; }
 public static implicit operator DogViewModel(Dog dm)
 {
 var vm= new DogViewModel{
 Id = dm.Id,
 Name = dm.Name,
 BirthDate = dm.BirthDate 
 };
 return vm;
 }
 public static implicit operator Dog(DogViewModel vm)
 {
 var dm = new Dog
 {
 Id = vm.Id,
 Name = vm.Name,
 BirthDate = vm.BirthDate 
 };
 return dm;
 }
}

This allows me to in my controller actionmethods easily map one class to another.

e.g.

 public async Task<IActionResult> Edit(int? id)
 {
 var dog= await _db.Dogs.FirstOrDefaultAsync(d => md.Id == id);
 DogViewModel dogVm = dog;
 ...
 }
 [HttpPost]
 public async Task<IActionResult> Edit(DogViewModel dogVm)
 {
 Dog dog= dogVm;
 ...
 }

In my index ActionMethod I need to map a list of items.

 public async Task<IActionResult> Index()
 {
 var dogs = await _db.Dogs.ToListAsync();
 var dogVms = new List<DogViewModel>();
 foreach (var dog in dogs)
 {
 DogViewModel dogVm = dog;
 dogVms.Add(dogVm);
 }
 return View(dogVms);
 }

Question: Is there a way in LINQ or some other way in C# to eliminate the above foreach clause to simplify this code?

asked Oct 23, 2015 at 9:10
\$\endgroup\$
3
  • \$\begingroup\$ You crate a List<MonthViewModel>() but you are adding DogViewModels - is this correct? Is DogViewModel derived from MonthViewModel? I cannot try it out because you didn' show the MonthViewModel but I think since you have an implicit cast operator this might work _db.Months.ToListAsync().Cast<DogViewModel>().ToList(); that repaces your loop. \$\endgroup\$ Commented Oct 23, 2015 at 10:25
  • \$\begingroup\$ Sorry was just a typo. I corrected it. Should read dog not month \$\endgroup\$ Commented Oct 23, 2015 at 10:59
  • \$\begingroup\$ I think your understanding of how ViewModel and Model work is not that good yet. Assigning a Model to morph into a VM is not a good practice. \$\endgroup\$ Commented Jun 8, 2018 at 4:54

2 Answers 2

3
\$\begingroup\$

Providing

var dogVms = new List<MonthViewModel>();

is meant to actually be

var dogVms = new List<DogViewModel>();

Then to use LINQ you could do

List<DogViewModel> dogVms = (from dog in dogs select (DogViewModel)dog).ToList();
answered Oct 23, 2015 at 10:34
\$\endgroup\$
0
1
\$\begingroup\$

You could also write;

var dogVms = dogs.Select<Dog, DogViewModel>(dog => dog);

(assuming you have implicit operators)

answered Dec 5, 2015 at 21:26
\$\endgroup\$
3
  • \$\begingroup\$ Hi! Welcome to Code Review. Please explain more on why your way is better. \$\endgroup\$ Commented Dec 5, 2015 at 21:39
  • \$\begingroup\$ To add on to Coffee's comment: Here, we expect answers that both provide a better way and explain why those ways are better. \$\endgroup\$ Commented Dec 5, 2015 at 22:02
  • \$\begingroup\$ hi guys. because it's shorter and seems more elegant :) \$\endgroup\$ Commented Dec 31, 2015 at 12:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.