我有一个products
表,其CategoryId
表示Categories
表中相应的主键。
ProductViewModel
public ProductVM(ProductDTO productDTO)
{
Id = productDTO.Id;
Name = productDTO.Name;
Description = productDTO.Description;
Price = productDTO.Price;
CategoryId = productDTO.CategoryId;
ImageName = productDTO.ImageName;
}
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
public decimal Price { get; set; }
public int? CategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
public string ImageName { get; set; }
public IEnumerable<string> GalleryImages { get; set; }
产品DTO
public class ProductDTO
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Slug { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int CategoryId { get; set; }
public string ImageName { get; set; }
[ForeignKey("CategoryId")]
public virtual CategoryDTO Category { get; set; }
}
这是我获得产品清单的方式:
List<ProductVM> productVM;
using (Db db = new Db())
{
productVM = db.Products
.ToArray()
.Select(x => new ProductVM(x))
.ToList();
}
正如您所看到的,我正在传递CategoryId
,我可以使用ProductVM
ViewModel在我的视图中显示它,但我也希望获得该类别的Name
那里也是。
我可以想到一些黑客,例如基于DB
从ViewModel
中的构造函数访问CategoryId
并以此方式分配,但我想看看是否有更优雅的解决方案?
底线 - 我的Name
表格中有一个Categories
列,我希望以最有效的方式将该名称传递给ProductVM
。
答案 0 :(得分:1)
为您的类别名称添加属性,例如
public string CategoryName { get; set; }
并修改构造函数以填充它
public ProductVM(ProductDTO productDTO)
{
CategoryName = productDTO.Category.Name;
....
并将查询修改为
List<ProductVM> productVM = db.Products.AsEnumerable().Include(x => x.Category)
.Select(x => new ProductVM(x)).ToList();
请注意,如果使用此参数进行编辑,则视图模型也需要无参数构造函数,否则将在POST方法中抛出异常。
另请注意,您不需要using (Db db = new Db())
答案 1 :(得分:0)
最佳解决方案如下(我删除了所有其他答案)
namespace Test
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
internal class Program
{
private static void Main(string[] args)
{
List<ProductVM> productVM;
//It doesn't matter if you use a using block or not
using (Db db = new Db())
{
db.Database.Log = Console.WriteLine;//To see the generated SQL
productVM = db.Products
.Include(p => p.Category)
.Select(p => new ProductVM
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
Price = p.Price,
CategoryId = p.CategoryId,
CategoryName = p.Category.Name,
ImageName = p.ImageName,
}).ToList();
}
Console.ReadKey();
}
}
public class Db : DbContext
{
public DbSet<ProductDTO> Products { get; set; }
public DbSet<CategoryDTO> Categories { get; set; }
}
public class ProductDTO
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Slug { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int CategoryId { get; set; }
public string ImageName { get; set; }
[ForeignKey("CategoryId")]
public virtual CategoryDTO Category { get; set; }
}
public class CategoryDTO
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class ProductVM
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
public decimal Price { get; set; }
public int? CategoryId { get; set; }
public string CategoryName { get; set; }
public string ImageName { get; set; }
}
}