[英]EF Core Many to Many Querying to join 3 tables
我有以下代碼:
public class ProductTbl
{
public override int Id { get; set; }
public string ProductName { get; set; }
public List<ProductManufacturer> ProductManufacturer { get; set; } //M2M
}
public class Manufacturer_LKP
{
public override int Id { get; set; }
public string ManufacturerName { get; set; }
public List<ProductManufacturer> ProductManufacturer { get; set; } //M2M
}
public class ProductManufacturer
{
public ProductTbl Product { get; set; }
public int ProductID { get; set; }
public Manufacturer_LKP Manufacturer { get; set; }
public int ManufacturerID { get; set; }
}
public class SupplierTbl
{
public int SupplierID { get; set; }
public string SupplierName { get; set; }
}
public class ProductSuppliertbl
{
public int Id { get; set; }
public ProductTbl Product { get; set; }
public int ProductID { get; set; }
public SuppilerTbl Supplier { get; set; }
public int SupplierID { get; set; }
}
*我需要編寫 Linq 查詢來連接所有 3 個表(Product、Manufacture、ProductManufacturer),以便在一次 DB 行程中同時獲取 ProductName 和 ManufatureName
*當我執行以下操作時,我錯過了 Manufacture 對象(Manufacture=Null)
DbSet<ProductTbl>()
.Where(a => a.Id == 5)
.AsNoTracking()
.Include(a => a.ProductType)
.Include(a => a.ProductManufacturer)
以上 Linq 只是將 Product 表與 ProductManufacture 表聯合起來,所以我無法獲得“ManufactureName”
那么有沒有什么辦法可以在一次 DB 行程中加入 3 個表以在 ProductName 旁邊獲得 ManufactureName ?
嘗試這個
var list = context.Set<ProductManufacturer>()
.Select(i => new
{
ProductName = i.Product.ProductName,
ManufacturerName = i.Manufacturer.ManufacturerName
})
.ToList();
嘗試加載相關數據時,投影是您的朋友。 多對多的問題是你說一個產品有很多制造商,同時它有很多供應商
產品需要引用該產品的 ProductSuppliers 以輕松管理眾多供應商的需求。
var productData = context.Products
.Select(p => new
{
p.ProductName,
ManufacturerNames = p.ProductManufacturers.Select(pm => pm.Manufacturer.ManufacturerName).ToList(),
SupplierNames = x.ProductSuppliers.Select(ps => ps.Supplier.SupplierName).ToList()
}).ToList();
這為您提供了一個產品列表,其中包含每個產品的相關制造商名稱和供應商名稱。 使用這些數據,您可以按照您認為合適的方式格式化輸出。
如果您想要實體本身,那么缺少的位是ThenInclude
:
var products = context.Products
.Include(p => p.ProductManufacturers)
.ThenInclude(pm => pm.Manufacturer)
.Include(p => p.ProductSuppliers)
.ThenInclude(ps => ps.Supplier)
.AsNoTracking()
.ToList();
這將加載整個實體圖。
如果您不想或不能在產品中放置 ProductSuppliers 集合,那么您可以完全從 ProductSupplier 構建查詢,但它有點混亂。
如果您使用的是 EF Core 5 並且您的加入實體 (ProductManufacturer/ProductSupplier) 只是對其各自實體的 FK 引用,那么您可以取消加入實體並讓 EF 在幕后管理它。 產品將只包含制造商的集合和供應商的集合。 這些仍然可以使用HasMany..WithMany
進行配置,但在沒有中間實體的情況下使查詢更加清晰。
IE
var productData = context.Products
.Select(p => new
{
p.ProductName,
ManufacturerNames = p.Manufacturers.Select(m => m.ManufacturerName).ToList(),
SupplierNames = x.Suppliers.Select(s => ps.SupplierName).ToList()
}).ToList();
和
var products = context.Products
.Include(p => p.Manufacturers)
.Include(p => p.Suppliers)
.AsNoTracking()
.ToList();
... 分別。 僅當您希望在加入實體中訪問其他屬性時,才需要中間加入實體。 (即 CreatedBy/At 等)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.