根据外键ID

时间:2016-11-09 10:45:36

标签: c# .net asp.net-mvc

我有一个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那里也是。

我可以想到一些黑客,例如基于DBViewModel中的构造函数访问CategoryId并以此方式分配,但我想看看是否有更优雅的解决方案?

底线 - 我的Name表格中有一个Categories列,我希望以最有效的方式将该名称传递给ProductVM

2 个答案:

答案 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; }
    }
}