更新在 EF 中添加相关行的行(多对多)

Update a row adding a relationed row in EF (many-to-many)

我有两个实体:OrderItem 以及它们之间的多对多关系。我有一个接收 ItemId 作为参数的方法,如下所示:

public void AddItems(int OrderId, int ItemId)
        {
            Item item = db.ItemSet.SingleOrDefault(i => i.Id == ItemId);
            Order order = db.OrderSet.SingleOrDefault(o => o.Id == OrderId);

            order.Items.Add(item);
            db.SaveChanges();
        }

ItemSettable中有很多行,所以第一个查询很重。有没有一种方法可以在不先在 "ItemSet" table 上进行查询的情况下将商品添加到订单中?我的意思是,我可以将 ItemId 直接添加到 Order.Items 或类似的东西吗?

        Item item = new Item { ID = ItemId };
        Order order = new Order { ID = OrderId };

        db.ItemSet.Attach(item);
        db.OrderSet.Attach(order);

        order.Items.Add(item);  

        db.SaveChanges();

请确保您的订单中包含此内容 class:

    public Order()
    {
        Items = new List<Item>();
    }

所以你不会在order.Items.Add(item);

中得到空指针异常

因此您可以对实体进行建模,因此:

public DbSet<Item> ItemSet {get;set;}
public DbSet<Order> OrderSet {get;set;}
public DbSet<ItemOrder> ItemOrders {get;set;}

public class Item
{
    public int Id {get;set;}
}

public class Order
{
    public int Id {get;set;}
}

public class ItemOrder
{
    [Key, Column(Order = 0)]
    public int ItemId {get;set;}

    [Key, Column(Order = 1)]
    public int OrderId {get;set;}
}

所以为了更新:

    public void AddItems(int OrderId, int ItemId)
    {
        var itemExists = db.ItemOrders.FirstOrDefault(x => x.OrderId == OrderId && x.ItemId == ItemId);

        if (itemExists != null) return;            

        db.ItemOrders.Add(new ItemOrder { OrderId = OrderId, ItemId = ItemId });

        db.SaveChanges();
    }

然后您可以使用 LINQ .Join() 进行查询,非常简单。

为了完整起见,OP 提到导航属性现在已经消失。所以如果你知道 OrderId 那么你可以简单地做:

var items = db.ItemOrders.GroupJoin(
                db.ItemSet,
                io => io.ItemId,
                i => i.Id,
                (itemOrder, items) => items)
              .ToList();

因此,为了引导您完成,GroupJoin 要求提供您要加入的数据的 IQueryable/IEnumerable

第二个参数是初始数据集的字段,即ItemOrders您要加入的数据集。

第三个参数是要加入的集合的字段,即ItemSet

第四个参数基本上是一个 Select,您会看到一个 Func 签名,大致 (ItemOrder itemInFirstSet, IEnumerable<Item> itemsThatAreJoined)

您可以将相同的逻辑应用于 LINQ Join 扩展。但不是 itemsThatAreJoined,而是 itemThatIsJoined。所以区别是 GroupJoin 会找到多个匹配的实体,Join 只会找到一个。

这不是详细的解释,更多的是概述