【问题标题】:Entity Framework : two inner joins on the same table实体框架:同一张表上的两个内连接
【发布时间】:2020-07-24 17:49:55
【问题描述】:

我有以下database schema and relation

我要做的是从ProductActiveIngredient 表中选择已知的productId,我想从ActiveIngredientOneActiveIngredientTwoActiveIngredientThreeActiveIngredientFour内部加入 ActiveIngredient 表和 ProductActiveIngredient

执行此查询将返回每个ActiveIngredientOneActiveIngredientTwo 列名称:

select 
    a.ActiveIngredientOne, b.ActiveIngredientName, c.ActiveIngredientName
from
    ProductActiveIngredient a
inner join 
    ActiveIngredient b on a.ActiveIngredientOne = b.ActiveIngredientId
inner join 
    ActiveIngredient c on a.ActiveIngredientTwo = c.ActiveIngredientId 

查询结果为:

query result

我想做的是使用实体框架进行此查询。

我的解决方案中编写了以下模型:

public class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string ProductGuid { set; get; }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductId { set; get; }
    [Required]
    [Display(Name = "Cost")]
    public int Cost { set; get; }
    [Required]
    [Display(Name = "Tax")]
    public int Tax { set; get; }
    [Required]
    [Display(Name = "Profit")]
    public int Profit { set; get; }
    [Required]
    [Display(Name = "Discount")]
    public int Discount { set; get; }
    [Required]
    [Display(Name = "Price")]
    public int Price { set; get; }
    [Required]
    [Display(Name = "Units")]
    public int Units { set; get; }
    [Required]
    [Display(Name = "Pack size")]
    public int PackSize { set; get; }
    [Display(Name = "Description")]
    public string Description { set; get; }
    [Display(Name = "Manufacturer id")]
    public int ManufacturerId { set; get; }
    public virtual Contact Contact { set; get; }
    public virtual ProductActiveIngredient ProductActiveIngredient { set; get; }
}

public class ProductActiveIngredient
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string ProductActiveIngredientGuid { set; get; }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductActiveIngredientId { set; get; }
    [Required]
    [Display(Name = "Active Ingredient 1")]
    public int ActiveIngredientOne { set; get; }
    //[Display(Name = "Active Ingredient 2")]
#nullable enable
    public int ActiveIngredientTwo { set; get; }
    public int ActiveIngredientThree { set; get; }
    public int ActiveIngredientFour { set; get; }
#nullable disable
    public int ProductId { set; get; }
    public int ForUser { set; get; }
    public virtual Product Product { set; get; }
    public virtual User User { set; get; }
    public virtual ActiveIngredient ActiveIngredient { set; get; }
}

public class ActiveIngredient
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string ActiveIngredientGuid { set; get; }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ActiveIngredientId { set; get; }
    [Required]
    [Display(Name = "Active ingredient name")]
    public string ActiveIngredientName { set; get; }
    public virtual ProductActiveIngredient ProductActiveIngredient { set; get; }
}

这是我的数据库上下文关系:

modelBuilder.Entity<Product>()
            .HasOne(pai => pai.ProductActiveIngredient)
            .WithOne(p => p.Product)
            .HasForeignKey<ProductActiveIngredient>(p => p.ProductActiveIngredientId);
modelBuilder.Entity<ActiveIngredient>()
            .HasOne(ai => ai.ProductActiveIngredient)
            .WithOne(aco => aco.ActiveIngredient)
            .HasForeignKey<ProductActiveIngredient>(a => a.ActiveIngredientOne);
modelBuilder.Entity<ActiveIngredient>()
            .HasOne(ai => ai.ProductActiveIngredient)
            .WithOne(aco => aco.ActiveIngredient)
            .HasForeignKey<ProductActiveIngredient>(a => a.ActiveIngredientTwo);
modelBuilder.Entity<ActiveIngredient>()
            .HasOne(ai => ai.ProductActiveIngredient)
            .WithOne(aco => aco.ActiveIngredient)
            .HasForeignKey<ProductActiveIngredient>(a => a.ActiveIngredientThree);
modelBuilder.Entity<ActiveIngredient>()
            .HasOne(ai => ai.ProductActiveIngredient)
            .WithOne(aco => aco.ActiveIngredient)
            .HasForeignKey<ProductActiveIngredient>(a => a.ActiveIngredientFour);

此 LinQ 查询执行良好,并获得与 T-SQL 查询相同的结果,但我需要在 EF 中而不是在 LinQ 中执行:

var s = from pac in _db.ProductActiveIngredient
    join ai in _db.ActiveIngredient on pac.ActiveIngredientOne equals ai.ActiveIngredientId
    join ai2 in _db.ActiveIngredient on pac.ActiveIngredientTwo equals ai2.ActiveIngredientId
    where pac.ProductId == productId
    select new
    {
        pac.ActiveIngredientOne,
        ai.ActiveIngredientName,
        pac.ActiveIngredientTwo,
        b2 = ai2.ActiveIngredientName
    };

有什么帮助吗?

【问题讨论】:

  • 您是否尝试过更改数据模型以使ProductActive Ingredient 之间存在多对多关系?这将消除对多个连接的需要。
  • 是的,现在可以正常使用了,谢谢。我所做的是在我的 ProductActiveIngredient 类和 ActiveIngredient 类中添加了另外三个模型。然后我使用了 .Include(x=>x.ProductActiveIngredientOne) .ThenInclude(z=>z._ActiveIngredientOne).FirstOrDefaultAsync();
  • 所以你没有理解@bbaird 的建议。

标签: c# sql-server entity-framework asp.net-core


【解决方案1】:

已经完成了,非常感谢。 我所做的是在我的 ProductActiveIngredient 类和 ActiveIngredient 类中添加另外三个虚拟属性。 然后我使用了 .Include(x=>x.ProductActiveIngredientOne) .ThenInclude(z=>z._ActiveIngredientOne).FirstOrDefaultAsync(); 并将我的数据库上下文更新为上述属性。

【讨论】:

    猜你喜欢
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多