【发布时间】:2020-07-24 17:49:55
【问题描述】:
我有以下database schema and relation
我要做的是从ProductActiveIngredient 表中选择已知的productId,我想从ActiveIngredientOne、ActiveIngredientTwo、ActiveIngredientThree 和ActiveIngredientFour内部加入 ActiveIngredient 表和 ProductActiveIngredient。
执行此查询将返回每个ActiveIngredientOne 和ActiveIngredientTwo 列名称:
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
查询结果为:
我想做的是使用实体框架进行此查询。
我的解决方案中编写了以下模型:
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
};
有什么帮助吗?
【问题讨论】:
-
您是否尝试过更改数据模型以使
Product和Active Ingredient之间存在多对多关系?这将消除对多个连接的需要。 -
是的,现在可以正常使用了,谢谢。我所做的是在我的 ProductActiveIngredient 类和 ActiveIngredient 类中添加了另外三个模型。然后我使用了 .Include(x=>x.ProductActiveIngredientOne) .ThenInclude(z=>z._ActiveIngredientOne).FirstOrDefaultAsync();
-
所以你没有理解@bbaird 的建议。
标签: c# sql-server entity-framework asp.net-core