如何从.NET中的多对多关系中获取数据?

问题描述 投票:0回答:1

我使用 .NET 制作了一个用于学习的 API。

这是一个简单的 API,其中有披萨和配料。我想获取数据库中的所有披萨及其成分。像这样的东西:

[
  {
    "id": 2,
    "name": "Pizza XYZ",
    "price": 4.5,
    "isPizzaOfTheWeek": false,
    "amount": 15,
    "pizzaIngredients": [
      {
         id: 1,
         name: 'Onion',
         price: '2.00',
         cost: '8.00'
      }
    ]
  },
]

我的实体是这些:

public class Pizza
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; } = null!;
    [Column(TypeName = "decimal(5,2)")]
    public decimal Price { get; set; }      
    public bool IsPizzaOfTheWeek { get; set; }
    public int Amount { get; set; }
    
    public List<PizzaIngredient> PizzaIngredients { get; set; } = null!;
}

public class Ingredient
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; } = null!;
    
    [Column(TypeName = "decimal(5,2)")]
    public decimal Price { get; set; }      // Price per 100 g

    public List<PizzaIngredient> PizzaIngredients { get; set; } = null!;
}

public class PizzaIngredient
{
    [Key]
    public int PizzaId { get; set; }
    public Pizza Pizza { get; set; } = null!;
    
    [Key]
    public int IngredientId { get; set; }
    public Ingredient Ingredient { get; set; } = null!;
    
    [Column(TypeName = "decimal(5,2)")]       
    public decimal Cost { get; set; } // Total Cost of this ingredient for this pizza
}

问题是我不知道该怎么做。

我尝试使用:

var pizzas = await _context.Pizza.Include(p => p.PizzaIngredients).ThenInclude(pi => pi.Ingredient).ToListAsync();

这个函数给我带来了所有的成分数据,但它也给我带来了重复的数据,因为“成分”具有属性,它也是一个

PizzaIngredients
的列表。

我希望一切都清楚。如果需要更多信息,我会写。

c# .net entity-framework-core
1个回答
0
投票

通常,如果不需要其中包含其他属性,我建议删除映射表。将价格移至披萨,因为它适用于披萨。除非你做了一个订单表。 Ypu 不需要在 FluentApi 中为多对多做任何事情

型号

public class Pizza
{
    public Pizza()
    {
       //Initialize the collection in Hashset for fast search
       this.Ingredients = new HashSet<Ingredients>();
    }

    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    [Column(TypeName = "decimal(5,2)")]
    public decimal Price { get; set; }      
    public bool IsPizzaOfTheWeek { get; set; }
    public int Amount { get; set; }
    public decimal Cost { get; set; }
    
    //Use a collection instead of a list to be able to convert it to HashSet
    public virtual ICollection<Ingredient> Ingredients { get; set; }
}

public class Ingredient
{
    public Ingredient()
    {
       //Initialize the collection in Hashset for fast search
       this.Pizzas = new HashSet<Pizza>();
    }

    [Key]
    public int Id { get; set; }
    public string Name { get; set; } = null!;
    
    [Column(TypeName = "decimal(5,2)")]
    public decimal Price { get; set; }      // Price per 100 g

    //Use a collection instead of a list to be able to convert it to HashSet
    public virtual ICollection<Pizza> Pizzas { get; set; }
}

//DtoModel
public class PizzaDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }      
    public bool IsPizzaOfTheWeek { get; set; }
    public int Amount { get; set; }
    public decimal Cost { get; set; } //Total cost of ingredients prices
    
    public List<Ingredient> Ingredients { get; set; };
}

服务

//Qerry
//All pizza ids you want with single query
var ids = new List<int> { 1, 4, 6, 22 };

var pizzas = await this.context.Pizzas
    .Where(x => ids.Contains(x.Id)) // Pizzas by ids
    .Where(x => x.Ingredients.Any(x => x.Name == name)) //Pizzas by ingredient
    .Select(x => new PizzaDto
    {
       Id = x.Id,
       Name = x.Name,
       Price = x.Price,
       IsPizzaOfTheWeek = x.IsPizzaOfTheWeek,
       Amount = x.Amount ,
       Cost = x.Ingredients.Sum(x => x.Price),
       Ingredients = x.Ingredients,
    }).ToListAsync();


//Save
var pizza = new Pizza
{
   Name = name,
   Price = price,
   IsPizzaOfTheWeek = isPizzaOfTheWeek,
   Amount = amount ,
   Cost = ingredients.Sum(x => x.Price),
   Ingredients = ingredients, //List of ingreadients
};

await this.context.AddAsync(pizza);
await this.context.SaveChangesAsync();
© www.soinside.com 2019 - 2024. All rights reserved.