Reputation: 1602
I have this entity model for a recursively structured category tree:
public class ProductCategory
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public int SortOrder { get; set; }
public ProductCategory ParentCategory { get; set; } //nav.prop to parent
public ICollection<ProductCategory> Children { get; set; } = new List<ProductCategory>();
public ICollection<ProductInCategory> ProductInCategory { get; set; }
public ICollection<FrontPageProduct> FrontPageProduct { get; set; } // Nav.prop. to front page product
// Recursive sorting:
public void RecursiveOrder()
{
Children = Children.OrderBy(o => o.SortOrder).ToList();
Children.ToList().ForEach(r => r.RecursiveOrder());
}
}
... and this, supposedly, matching ViewModel:
public class ViewModelProductCategory
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public int SortOrder { get; set; }
public bool Checked { get; set; } // Used for assigning a product to multiple categories in Product/Edit
// Nav.props:
public ViewModelProductCategory ParentCategory { get; set; } // Nav.prop. to parent
public ICollection<ViewModelProductCategory> Children { get; set; } // Nav.prop. to children
public IEnumerable<ViewModelProduct> Products { get; set; } // Products in this category
public IEnumerable<ViewModelFrontPageProduct> FrontPageProducts { get; set; }
public string ProductCountInfo { get { return Products?.Count().ToString() ?? "0"; } }
}
When I try to populate the viewmodel, like this:
List<ProductCategory> DbM =
await _context.ProductCategories
.Include(c => c.Children)
.Where(x => x.ParentId == null)
.OrderBy(o => o.SortOrder)
.ToListAsync();
foreach (var item in DbM)
{
VMSelectCategories.Add(
new ViewModelProductCategory{
Id = item.Id,
Children = item.Children,
Title = item.Title
});
}
VisualStudio screams at me that it can't implicitly convert ProductCategory
to ViewModelCategory
. This happens at Children = item.Children
.
Why isn't it working? Can't I have additional properties in the viewmodel that I use unrelated to the original entity model? Like Checked
and ProductCountInfo
?
Upvotes: 1
Views: 50
Reputation: 54427
In this line:
Children = item.Children,
Children
is the ViewModelProductCategory.Children
property, which is type ICollection<ViewModelProductCategory>
, while item.Children
is the ProductCategory.Children
property, which is type ICollection<ProductCategory>
. They are different types and neither inherits or implements the other so why would you expect to be able to assign an object of one type to a property of the other type? Would you expect this to work:
var list1 = new List<int> {1, 2, 3};
List<string> list2 = list1;
Of course not (I hope) because assigning a List<int>
object to a List<string>
variable would be silly. What you're trying to do is exactly the same. You need to provide some way to convert from one type to the other and then implement that in your code. An option for that might be like this:
Children = item.Children.Select(pc => MapToViewModel(pc)).ToList(),
where MapToViewModel
is a method that you write to create a ViewModelProductCategory
and populate its properties from a ProductCategory
parameter.
You might also look at using something like AutoMapper.
Upvotes: 1