[英]Correct disposing using Repository and Unit Work patterns with Entity Framework?
[英]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 ID
和Supplier 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 那些例如Categories
和Suppliers
,它与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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.