0

我已经构建了一个 .Net Mvc 4 应用程序,现在我想用 REST 扩展它。

我正在使用实体框架,但遇到以下问题。

我的目标是建立一个系统,其中类别具有多个产品,并且产品可以属于多个类别。

如下:

public class Categorie
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Naam { get; set; }
    [Required]
    public string Omschrijving { get; set; }
    public byte[] Plaatje { get; set; }
    private List<Product> producten;
    public virtual List<Product> Producten
    {
        get { return producten; }   
        set { producten = value; }
    }
}

public class Product
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Naam { get; set; }
        [Required]
        public string Omschrijving { get; set; }
        [Required]
        public double Prijs { get; set; }
        private List<Categorie> categorien = new List<Categorie>();

        public virtual List<Categorie> Categorien
        {
            get { return categorien; }
            set { categorien = value; }
        }
        [Required]
        public byte[] Plaatje { get; set; }
    }

注意:那里有虚拟属性,以便我的实体框架创建一个合并表。通常它将所有类别链接到产品,反之亦然。

我的休息看起来像:

// GET api/Rest/5
    public Product GetProduct(int id)
    {
        Product product = db.Producten.Find(id);
        Product newProduct = new Product();
        if (product == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }
        else
        {
            product.Categorien = null;
        }
        newProduct.Id = product.Id;
        newProduct.Naam = product.Naam;
        newProduct.Omschrijving = product.Omschrijving;
        newProduct.Plaatje = product.Plaatje;
        newProduct.Prijs = product.Prijs;
        newProduct.Categorien = product.Categorien;
        return newProduct;
    }

第一个问题:我不能发送任何产品,只要它有一个类别。我必须让它为空。第二个问题:由于第一个问题,我无法发送原始产品。

4

1 回答 1

1

我假设您的问题在于序列化期间的循环引用,因为类别引用多个产品而产品引用多个类别。一种解决方案是使用数据传输对象 (DTO),而不是返回用于 EF 的直接实体。为了便于将您的实体映射到 DTO,我将使用AutoMapper。这本质上是您在 REST API 方法中创建 newProduct 实例时所做的事情,但 AutoMapper 将硬编码和苦差事从映射中解脱出来。您的产品 DTO 看起来非常相似,但它们没有虚拟导航属性或 EF 所需的属性。产品的 DTO 看起来像这样。

public class Categorie
{
    public int Id { get; set; }
    public string Naam { get; set; }
    public string Omschrijving { get; set; }
    public byte[] Plaatje { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Naam { get; set; }
    public string Omschrijving { get; set; }
    public double Prijs { get; set; }
    public List<Categorie> categorien = new List<Categorie>();

    public List<Categorie> Categorien
    {
        get { return categorien; }
        set { categorien = value; }
    }
    public byte[] Plaatje { get; set; }
}

请注意,类别的 DTO 不包含产品列表,因为在这种情况下您需要产品列表。如果您保持 DTO 的字段名称与您的实体相同,AutoMapper 将自动处理映射。我通常为 DTO 保留相同的类名,并通过使用不同的命名空间将它们与实体区分开来。您的 REST API 方法看起来像这样。

// GET api/Rest/5
public Product GetProduct(int id)
{
    Product product = db.Producten.Find(id);
    return Mapper.Map<Product, Dto.Product>(product);
}
于 2012-10-29T18:06:44.817 回答