簡體   English   中英

如何在 Entity Framework Core 中使用通用存儲庫和工作單元模式時獲取外鍵鏈接值

[英]How to get foreign key linked values while using generic repository and unit of work patterns with Entity Framework Core

我是 Entity Framework Core 7 和 ASP.NET Core 7 MVC 的新手。 我正在使用 Northwind 數據庫學習這些概念。 我在 EF Core 之上使用通用存儲庫和 UnitOfWork 模式進行數據訪問。

我創建了一個ProductsController並在視圖中,我想在網格視圖中顯示產品的所有行以及相應的類別名稱和供應商名稱,因為Products表具有Category IDSupplier ID作為外鍵。

在純 EF 中,我可以使用.Include來獲取這兩個值。 但是,它在通用存儲庫模式中不可用。 我在這里分享這三個表的關系圖:

在此處輸入圖像描述

代碼:

// GET: ProductController
public ActionResult Index()
{
    var products = _unitOfWork.Product.GetAll();
    return View(products);
}

// Product model
public partial class Product
{
     public int ProductId { get; set; }
     [DisplayName("Product Name")]
     public string ProductName { get; set; } = null!;

     public int? SupplierId { get; set; }

     public int? CategoryId { get; set; }
     [DisplayName("Quantity Per Unit")]
     public string? QuantityPerUnit { get; set; }
     [DataType(DataType.Currency)]
     public decimal? UnitPrice { get; set; }

     public short? UnitsInStock { get; set; }
     public short? UnitsOnOrder { get; set; }
     public short? ReorderLevel { get; set; }
     public bool Discontinued { get; set; }

     public virtual Category? Category { get; set; }

     public virtual ICollection<OrderDetail> OrderDetails { get; 
        } = new List<OrderDetail>   ();

     public virtual Supplier? Supplier { get; set; }
}

UnitOfWork模式中,這三個表是單獨可用的。 本質上,我想知道如何從Products集合中獲取類別名稱和供應商名稱。

您可以使用 LINQ Join 方法連接這三個表,然后將結果投影到 model object 中,其中包含 Category Name 和 Supplier Name 的屬性。

var result = from p in _unitOfWork.Product.GetAll()
    join c in _unitOfWork.Category.GetAll() on p.CategoryId equals c.CategoryId
    join s in _unitOfWork.Supplier.GetAll() on p.SupplierId equals s.SupplierId
    select new {
    p.ProductId,
    p.ProductName,
    c.CategoryName,
    s.CompanyName
    };
    
return View(result);

在視圖中,您可以訪問 model object 的 CategoryName 和 SupplierName 屬性。希望這對您有所幫助。

在 UnitOfWork 模式中,這三個表是單獨可用的。 本質上,我想知道如何從產品集合中獲取類別名稱和供應商名稱。

好吧,因為你有Product class 和這個 class 你有導航 class 那些例如CategoriesSuppliers ,它與Product class導航 class有外部表關系

public class Categories
    {
        [Key]
        public int CategoryID { get; set; }
        public string? CategoryName { get; set; }
    }


public class Suppliers
    {
        [Key]
        public int SupplierID { get; set; }
        public string? CompanyName { get; set; }
        public string? ContactName { get; set; }
    }

如何從工作單元模式中的導航表加載相關實體:

在您的場景中,我們可以將我們的GenericRepository擴展到 Product Repository 然后我們可以使用.Include object 這有助於從相關表屬性中查詢數據,這將更加方便和高效。 在您的場景中,當我們同時查詢Product表時,我們也想獲取與其他表相關的數據,所以請看下面:

產品的 UnitOfWork 存儲庫:

public class ProductRepository : GenericRepository<Product>, IProductReposiotry
    {
        public ProductRepository(ApplicationDbContext context, ILogger logger) : base(context, logger) { }
        public override async Task<IEnumerable<Product>> All()
        {
            try
            {
                var products = context.Products.Include(cat => cat.Category).Include(sup=>sup.Supplier).ToList();
                return await dbSet.ToListAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "{Repo} All function error", typeof(ProductRepository));
                return new List<Product>();
            }
        }
    }

工作單元 DbContext:

public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        
        public DbSet<Product> Products { get; set; }
        public DbSet<Categories> Categories { get; set; }
        public DbSet<Suppliers> Suppliers { get; set; }
       
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
           
            modelBuilder.Entity<Product>().ToTable("Products");
            modelBuilder.Entity<Categories>().ToTable("Categories");
            modelBuilder.Entity<Suppliers>().ToTable("Suppliers");
           
        }

    }

注意:請確保Northwind數據庫、屬性和您的 class 遵循相同的大小寫。

工作單元 Controller:

public class UnitOfWorkProductController : Controller
    {
        private readonly ILogger<UnitOfWorkProductViewController> _logger;
        private readonly IUnitOfWork _unitOfWork;

        public UnitOfWorkProductViewController(
            ILogger<UnitOfWorkProductViewController> logger,
            IUnitOfWork unitOfWork)
        {
            _logger = logger;
            _unitOfWork = unitOfWork;
        }
        public async Task<IActionResult> Index()
        {
            var products = await _unitOfWork.Products.All();
            return View(products);
        }
    }

看法:

@model IEnumerable<YourProjectName.Models.Product>


<table class="table">
    <thead>
        <tr>
            <th>ProductId
            <th>ProductName
            <th>Supplier Name
            <th>Category Name
            <th>UnitPrice
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.ProductId</td>
                <td>@item.ProductName</td>
                <td>@item.Supplier?.CompanyName</td>
                <td>@item.Category?.CategoryName</td>
                <td>@item.UnitPrice</td>
            </tr>
        }
    </tbody>
</table>

Output: 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM