通过ID C#APi

问题描述

我正在建立一个编辑现有配方的项目

请注意--每个食谱可以包含多个成分组 (这是我构建此项目的重点)

  1. 食谱表(食谱ID,名称等)
  2. 每个配方的成分组链接 ChartsForOneRecipe (组ID,组名称:(以调味料为基础))
  3. 成分表(ID和名称
  4. 具有所有成分组 ingredientsInChart 的成分列表的表(每种成分的ID,其所属的成分组的ID,成分ID,数量等)

有人知道我如何找出与一个成分组相关的成分名称吗? 在C#MVC中,当然不在sql

我的问题是:

如何在一个功能中执行此操作? 如何正确编写它会起作用。 如果有可能不复制或创建新表。

注意 我的桌子上还没有任何FK。 最后,我需要从数据库获取每个配方的成分组。 并且所有成分组都在一个表中,并且只有成分的ID,组的ID,而没有名称

我已经开始编写此功能

在“配方”控制器中:

mydata db = new data()
private List<ChartsForOneRecipe> lchart;
  1. 函数可返回属于某个特定配方的所有组,该函数运行良好

     [HttpGet]
     public IHttpActionResult GetTheNamesOfChartsByRecipeId(int RecipeId)
     {
    
         lchart = db.ChartsForOneRecipe.Where(ch => ch.recipeId == RecipeId).ToList();
    
         return base.Ok(lchart);
    
     }
    
  2. 一个函数,它返回特定组配料中的所有配料,但不起作用

     [HttpGet]//return all ingredients in a chart by getting chartid 
     public IHttpActionResult GetAlltheIngredientsInChart(int ChartId)
     {
    
         var q = from ing in db.Ingredients
                 from ingch in db.IngredientsInChart
                 where (ing.ingredientID == ingch.ingredientsInChartId && ingch.chartId == ChartId)
                 select new
                 { ing.ingredientID,ing.name };
    
         return Ok(q);
    

}

解决方法

考虑到您正在使用EF6 Code First,并用各自的Data Annotation定义了模型来设置密钥,如下所示:

public class Ingredients
{
    [Key]
    public int IngredientId { get; set; }
    public string Name { get; set; }
    
    //Begin Other irrelevant attributes
    //...
    //End irrelevant attributes
    
    //Navigation property - THIS IS IMPORTANT
    [ForeignKey("IngredientsInChartId")]
    public ICollection<IngredientsInChart> IngredientsInChart { get; set; }
}

public class IngredientsInChart
{
    [Key]
    public int ChartId { get; set; }
    public string Name { get; set; }
    
    //Begin Other irrelevant attributes
    //...
    //End irrelevant attributes
    
    //Optional,on using FLUENT-API for seeding data (Migration)
    public int IngredientsInChartId { get; set; }
    
    //Navigation property - THIS IS IMPORTANT
    [ForeignKey("IngredientsInChartId")]
    public Ingredients Ingredient { get; set; }
}

或者您可能更愿意使用FluentAPI来设置您的上下文:

public class MyData : DbContext
{
    public virtual DbSet<ChartsForOneRecipe> ChartsForOneRecipe { get; set; }
    public virtual DbSet<Recipe> Recipe { get; set; }
    
    //Other irrelevant DBSet properties

    public MyData(DbContextOptions<PharmaDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Primary keys

        modelBuilder.Entity<Ingredients>()
                    .Property(c => c.IngredientId)
                    .UseIdentityAlwaysColumn();        

        modelBuilder.Entity<IngredientsInChart>()
                    .Property(c => c.ChartId)
                    .UseIdentityAlwaysColumn();        

        //Foreign keys
        modelBuilder.Entity<Ingredients>()
                    .HasMany(c => c.IngredientsInChart)
                    .WithOne(k => k.Ingredient)
                    .HasForeignKey(fk => fk.IngredientsInChartId);

        modelBuilder.Entity<IngredientsInChart>()
                    .HasOne(k => k.Ingredient)
                    .WithMany(c => c.IngredientsInChart)
                    .HasForeignKey(fk => fk.IngredientsInChartId);
        
    }
}

最后,我们可以按以下方式加载数据:

急切加载

使用紧急加载方法,必须先加载所有 Ingredient ,然后再加载相关的 IngredientsInChart

[HttpGet]//return all ingredients in a chart by getting chartid 
public IHttpActionResult GetAlltheIngredientsInChart(int ChartId)
{
    var ingredients = db.Ingredients.ToList();

    var q = db.IngredientsInChart.Where(ingch => ingch.Id == ChartId)
                                 .Include(ingch => ingch.Ingredient)
                                 .Select(ingch => new { ingch.IngredientsInChartId,ingch.Ingredient.Name })
                                 .ToList();

    return Ok(q);
}

延迟加载

您不需要加载成分(删除var ingredients = db.Ingredients.ToList();Include(ingch => ingch.Ingredient))。但是,您可能需要按照以下步骤安装EF Proxy Nuget Package并在Startup项目中进行设置:

public void ConfigureServices(IServiceCollection services)
{
    #region Database configuration

    // Database configuration
    services.AddDbContext<MyData>(options =>
        options.UseLazyLoadingProxies()
               .UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));

    #endregion Database configuration
}

为进一步阅读,我强烈建议阅读:

,

前提是您具有在以下查询中可以在IngredientsInChart中设置的导航属性Ingredients

var q = db.IngredientsInChart.Where(inc => inc.chartId == ChartId)
                             .Include(inc => inc.Ingredient)
                             .Select(inc => new { 
                                           inc.ingredientsInChartId,inc.Ingredient.name 
                                     }).ToList();