Entity Framework多对多查询指定订单菜单项及ListView展示方法
问题说明
现有Order(订单)、MenuItem(菜单项)两张数据表,二者为多对多关联关系,通过中间实体OrderMenuItem完成关联映射,相关实体定义与EF Core配置如下:
Order实体
public class Order { [Key] public int OrderId { get; set; } public DateTime OrderDate { get; set; } public string Comments { get; set; } public string OrderStatus { get; set; } public string WaiterName { get; set; } public double TotalPrice { get; set; } public virtual ICollection<MenuItem> MenuItems { get; set; } }
MenuItem实体
public class MenuItem { [Key] public int MenuItemId { get; set; } public string Name { get; set; } public double Price { get; set; } public int MenuItemTypeId { get; set; } public MenuItemType MenuItemType { get; set; } public virtual ICollection<Order> Orders { get; set; } }
中间关联实体OrderMenuItem
public class OrderMenuItem { public int MenuItemId { get; set; } public int OrderId { get; set; } public Order Order { get; set; } public MenuItem MenuItem { get; set; } }
多对多Fluent API配置
modelBuilder.Entity<MenuItem>() .HasMany(m => m.Orders) .WithMany(o => o.MenuItems) .UsingEntity<OrderMenuItem>( x => x.HasOne(x => x.Order) .WithMany().HasForeignKey(x => x.OrderId), x => x.HasOne(x => x.MenuItem) .WithMany().HasForeignKey(x => x.MenuItemId) );
需求:检索特定订单下关联的所有MenuItem数据,并通过ListView控件完成数据展示。
实现步骤
1. 查询特定订单关联的MenuItem数据
可根据业务场景选择以下任意一种查询方式,两种方式均能返回正确的关联数据:
- 方式一:通过Order导航属性预加载(需要同时使用订单本身信息时选择该方式)
// 替换为实际需要查询的订单ID int targetOrderId = 1; using var dbContext = new YourAppDbContext(); // 预加载关联的MenuItems集合 var targetOrder = dbContext.Orders .Include(o => o.MenuItems) .FirstOrDefault(o => o.OrderId == targetOrderId); // 拿到关联菜单项集合,订单不存在时返回空集合避免空引用异常 List<MenuItem> relatedMenuItems = targetOrder?.MenuItems.ToList() ?? new List<MenuItem>();
- 方式二:直接通过中间表查询(仅需要菜单项数据时选择该方式,查询性能更高)
int targetOrderId = 1; using var dbContext = new YourAppDbContext(); var relatedMenuItems = dbContext.Set<OrderMenuItem>() .Where(om => om.OrderId == targetOrderId) .Select(om => om.MenuItem) .ToList();
2. 绑定数据到ListView控件展示
以下为WinForm平台下的实现代码,WPF平台可直接将查询结果赋值给ListView的ItemsSource属性,配合ItemTemplate配置展示列即可。
第一步:初始化ListView配置
将以下代码放在窗体构造函数或者Load事件中,初始化列表视图模式和展示列:
// 设置列表为详情展示模式 listView1.View = View.Details; // 开启整行选中效果 listView1.FullRowSelect = true; // 添加展示列,参数依次为列标题、列宽度 listView1.Columns.Add("菜品ID", 70); listView1.Columns.Add("菜品名称", 200); listView1.Columns.Add("单价", 80);
第二步:加载查询到的菜单项数据到控件
// 清空控件原有数据 listView1.Items.Clear(); foreach (var menuItem in relatedMenuItems) { // 第一列对应MenuItemId var item = new ListViewItem(menuItem.MenuItemId.ToString()); // 追加其他列数据 item.SubItems.Add(menuItem.Name); item.SubItems.Add(menuItem.Price.ToString("0.00")); // 将原始菜单项对象存在Tag属性,方便后续获取选中项的原始数据 item.Tag = menuItem; listView1.Items.Add(item); }
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

