【问题标题】:Entity Framework - parent child table update in single transation实体框架 - 单个事务中的父子表更新
【发布时间】:2016-11-03 08:22:23
【问题描述】:

我正在处理在UserOrders 表之间存在父子关系的应用程序。下面是表结构:

用户:

Column  | DataType  | Constraint
--------|-----------|-------------
UserId  | int       | Primary key
Username| varchar   |
Email   | varchar   |
IsActive| bit       |

订单:

Column  | DataType  | Constraint
--------|-----------|----------
OrderId | int       | Primary key
UserId  | int       | Foreign key to User.UserId
Type    | smallint  |
Quantity| smallint  |

根据我必须一次性更新用户及其订单的功能,可以动态添加、删除或更新订单。

我正在使用 Entity Framework 6.0,但我找不到在单个事务中更新父表 (user) 和子表 (order) 的最佳解决方案。

谁能解释实现这种功能的最佳方法?

下面是我正在使用的代码:

请注意我正在使用 AutoMapper 将对象映射到实体

public bool ManageUser(UserModel userDetails, string deletedOrders)
{
    var isSuccess = false;
    try
    {
        using (var entity = new UserEntity())
        {
            if (userDetails.UserId == 0)
            {
                entity.Users.Add(Mapper.Map<User>(userDetails));
            }
            else
            {
                var userToEdit = Mapper.Map<User>(userDetails);

                foreach (var item in userToEdit.Orders)
                {
                    if (item.OrderId == 0)
                    {
                        entity.Entry(item).State = System.Data.Entity.EntityState.Added;
                    }
                    else
                    {
                        entity.Entry(item).State = System.Data.Entity.EntityState.Modified;
                    }
                }

                /*** 
                * How to Write a code here to remove orders using deletedOrders parameter
                * Note: deletedOrders contains comma separated Id of the orders which needs to be removed. e.g. "1,5,6" 
                ****/

                entity.Entry(userToEdit).State = System.Data.Entity.EntityState.Modified;
            }

            entity.SaveChanges();
            isSuccess = true;
        }

    }
    catch (Exception ex)
    {

    }

    return isSuccess;
}

注意:这只是一个简单的代码。但是,如果我将有多个子表,例如 Order 怎么办?如果我遵循相同的做法,那么代码将变得复杂且难以处理。因此,为此类情况寻找最佳方法。

【问题讨论】:

  • 向我们展示您现在拥有的代码!
  • @marc_s:我添加了一个代码。请参阅让我感到困惑的多行 cmets。
  • 调用 SaveChanges 时,上下文中的所有更改都会在单个事务中写入数据库。这样你就完成了。
  • @SirRufo:你是对的。但我也想对已删除的订单执行删除操作。我无法理解。
  • 找到订单,然后将其从 DbSet 中删除或将该实体的状态设置为已删除

标签: c# asp.net-mvc entity-framework entity-framework-6


【解决方案1】:

对于应该删除的实体,不必访问数据库。

  1. 如果userDetails.Orders 包含应删除的订单,则在foreach (var item in userToEdit.Orders) 循环中将其状态更改为System.Data.Entity.EntityState.Deleted

  2. 如果没有,您只需创建具有合适 id 的,附加它们,然后将它们的 EntityState 也更改为 Deleted

    var ordersToDelete = deletedOrders.Split(new[] {','},
      StringSplitOptions.RemoveEmptyEntries).Select(x => new Order 
        { 
            Id = int.Parse(x.Trim())
        })
        .ToList();
    
    ordersToDelete.ForEach(o => 
        entity.Entry(x).State = System.Data.Entity.EntityState.Deleted);
    

【讨论】:

  • #1 的替代方法:inf foreach 循环检查 orderId 是否属于 deletedOrders,然后将其从 userToEdit.Orders 中删除。但在这种情况下,将 foreach 更改为 for 循环。
  • 但是,您对更多子表有什么建议并降低复杂性吗?
  • 您是否会将要删除的每个子类型的 id 作为单独的方法参数传递?在那种情况下,也许泛型 + 对象实例化操作?
猜你喜欢
  • 1970-01-01
  • 2020-12-10
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多