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?
2 Answers 2
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();
You could also write;
var dogVms = dogs.Select<Dog, DogViewModel>(dog => dog);
(assuming you have implicit operators)
-
\$\begingroup\$ Hi! Welcome to Code Review. Please explain more on why your way is better. \$\endgroup\$TheCoffeeCup– TheCoffeeCup2015年12月05日 21:39:59 +00:00Commented 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\$anon– anon2015年12月05日 22:02:57 +00:00Commented Dec 5, 2015 at 22:02
-
\$\begingroup\$ hi guys. because it's shorter and seems more elegant :) \$\endgroup\$Christian– Christian2015年12月31日 12:51:19 +00:00Commented Dec 31, 2015 at 12:51
List<MonthViewModel>()
but you are addingDogViewModel
s - is this correct? IsDogViewModel
derived fromMonthViewModel
? I cannot try it out because you didn' show theMonthViewModel
but I think since you have an implicit cast operator this might work_db.Months.ToListAsync().Cast<DogViewModel>().ToList();
that repaces your loop. \$\endgroup\$