面试题答案
一键面试- 设计实体类:
- 定义
Customer
类,包含Id
、Name
等属性,以及一个ICollection<Order>
导航属性来表示该客户的订单。
public class Customer { public int Id { get; set; } public string Name { get; set; } public ICollection<Order> Orders { get; set; } }
- 定义
Order
类,包含Id
、OrderDate
等属性,一个Customer
导航属性表示下单的客户,以及一个ICollection<Product>
导航属性表示订单中的产品。
public class Order { public int Id { get; set; } public DateTime OrderDate { get; set; } public Customer Customer { get; set; } public ICollection<Product> Products { get; set; } }
- 定义
Product
类,包含Id
、Name
、Price
等属性。
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }
- 定义
- 配置多对多关系:
在
DbContext
的OnModelCreating
方法中配置多对多关系。protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Order>() .HasOne(o => o.Customer) .WithMany(c => c.Orders) .HasForeignKey(o => o.CustomerId); modelBuilder.Entity<Order>() .HasMany(o => o.Products) .WithMany() .UsingEntity(j => j.ToTable("OrderProduct")); }
- 数据访问层设计:
- 创建一个接口
ICustomerProductRepository
来定义获取客户购买产品列表的方法。
public interface ICustomerProductRepository { Task<List<Product>> GetCustomerProductsAsync(int customerId); }
- 实现该接口,在实现类
CustomerProductRepository
中使用DbContext
进行查询。
public class CustomerProductRepository : ICustomerProductRepository { private readonly YourDbContext _context; public CustomerProductRepository(YourDbContext context) { _context = context; } public async Task<List<Product>> GetCustomerProductsAsync(int customerId) { return await _context.Customers .Where(c => c.Id == customerId) .SelectMany(c => c.Orders.SelectMany(o => o.Products)) .Distinct() .ToListAsync(); } }
- 创建一个接口
- 优化查询:
- 索引优化:
- 为
Customer
表的Id
列创建索引,这在Where
子句中使用,通常EF Core会自动为作为主键的Id
列创建索引。 - 为
Order
表的CustomerId
列创建索引,因为在关联Customer
和Order
表时会使用该列。 - 为
OrderProduct
连接表的OrderId
和ProductId
列创建索引,因为在多对多关系查询中会使用这两列。
- 为
- 分页处理:如果数据量过大,考虑分页处理。例如,修改
GetCustomerProductsAsync
方法支持分页。
public async Task<List<Product>> GetCustomerProductsAsync(int customerId, int pageNumber, int pageSize) { return await _context.Customers .Where(c => c.Id == customerId) .SelectMany(c => c.Orders.SelectMany(o => o.Products)) .Distinct() .Skip((pageNumber - 1) * pageSize) .Take(pageSize) .ToListAsync(); }
- 缓存机制:可以使用缓存来减少数据库的查询压力。例如,使用
MemoryCache
或者分布式缓存(如Redis)。如果客户购买的产品列表不经常变化,可以将查询结果缓存起来。
private readonly IMemoryCache _memoryCache; public CustomerProductRepository(YourDbContext context, IMemoryCache memoryCache) { _context = context; _memoryCache = memoryCache; } public async Task<List<Product>> GetCustomerProductsAsync(int customerId) { if (_memoryCache.TryGetValue($"Customer_{customerId}_Products", out List<Product> products)) { return products; } products = await _context.Customers .Where(c => c.Id == customerId) .SelectMany(c => c.Orders.SelectMany(o => o.Products)) .Distinct() .ToListAsync(); _memoryCache.Set($"Customer_{customerId}_Products", products, TimeSpan.FromMinutes(10)); return products; }
- 索引优化: