【问题标题】:Entity framework 6 : generic method AddOrUpdate实体框架 6:通用方法 AddOrUpdate
【发布时间】:2016-10-11 13:17:42
【问题描述】:

我花了很多时间尝试实现一个通用方法来添加或更新具有相关实体(一对多关系)的实体,但我卡住了......

该方法必须接收2个参数,第一个是父级,第二个是子级。目标是将子实体保存到父实体中(如果不存在则添加或更新)

有通用方法签名:

    public static bool AddOrUpdate<T,U>(T ItemToSave,U ItemRelated, int ID) where T : class where U : class
    {
        using (var context = new dbContext())
        {                
            var parent = context.Set<T>().Find(ID);
            if (parent == null) return;
            // how to retrieve now the child (ItemRelated) from the parent (ItemToSave) in order to add into it or update ?

            return context.SaveChanges() > 0;
        }
    }

此方法位于静态类“服务”中 我希望能够从任何类调用 Service.AddOrUpdate(Order _order, OrderLine _orderline, _order.OrderId)。

我一直在从父母那里检索孩子并添加或更新它。

谁能帮我实现这个目标?

【问题讨论】:

  • 那么您到底尝试了什么? “??”显然行不通
  • 对不起,我完成了我的问题
  • 不,它们是 2 个实体集,ItemToSave 可以有 0 个或多个 ItemRelated

标签: c# entity-framework generics entity


【解决方案1】:

在给定的约束下,这是不可能的。仔细想想——你给出的唯一限制是每个都必须是一个类。这并不能保证存在父子关系,更不用说如何定义该关系了。

泛型不是魔法。它们只是允许您以预定义的方式处理项目。在我们编写泛型方法之前,交互的定义必须存在。

【讨论】:

    【解决方案2】:

    您的 ItemRrelated 应该实现一些具有 parentId 属性的接口。 然后,如果它不存在,您可以将其添加到 DbSet。

    var existingItemRelated == context.Set<U>().SingleOrDefault(ir => ir.ParentId == ItemRelated.ParentId && (/*your criteria to determine if child item equals the one in DB*/));
    

    如果不存在则添加,如果存在则编辑。

    编辑

    此外,如果您不想为具有父项的实体提供通用接口,您可以将表达式传递给此方法,以确定子实体是否具有相同的父项

    public static bool AddOrUpdate<T, U>(T ItemToSave, U ItemRelated, int ID, Expression<Func<U,bool>> sameParentsExpression) where T : class where U : class
    {
        using (var context = new dbContext())
        {
            var parent = context.Set<T>().Find(ID);
            if (parent == null) return false;
            // how to retrieve now the child (ItemRelated) from the parent (ItemToSave) in order to add into it or update ?
            var existingItemRelated = context.Set<U>()
                                        .Where(sameParentsExpression)
                                        .SingleOrDefault(/*your criteria to determine if child item equals the one in DB*/);
    
            return context.SaveChanges() > 0;
        }
    }
    

    并像调用它一样调用它

    AddOrUpdate(order, orderline, order.OrderId, ol => ol.OrderId == order.OrderId)
    

    【讨论】:

    • "ir.ParentId" 不起作用,因为我们不知道 parent 的主键,因为它是通用的(T 可以是任何类)
    • T 可以是任何与孩子的父 ID 无关的类。正如我所说,U 类应该实现一些具有 ParentId 属性的接口。换句话说,您应该将 U 限制为“where U : IChildWithParentId”
    • Konstantin Ershov 我在我的问题中给了你更多的解释,你能更明确地描述你的解决方案吗?
    • 那么现在如何在上下文中将 'existingItemRelated' 添加到 'parent' ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多