在Linq to Entity中使用Func作为通用方法参数

射手

我想基于实体框架创建函数,该函数将更新SQL数据库中的表。

该表具有父子关系,因此我基于来更新一堆孩子parentID

我想拥有一个泛型函数,而且我不知道如何从编译时不知道其定义的对象中获取ID。

我尝试使用Func它可能非常整洁,但不能在Linq-To-Entities中使用。

代码:

protected static void update<TEntity>(DbSet<TEntity> set, int parentID,
  List<TEntity> entities, Func<TEntity, bool> isNew, Func<TEntity, int> getID = null, 
  Func<TEntity, int> getParentID, Action<TEntity, TEntity> updateSingleEntity)
        where TEntity : class
    {
        var currentIDs = entities.Select(e => getID(e));

        var newEntities = entities.Where(e => isNew(e));
        var existingEntities = entities.Where(e => !isNew(e));

        var deletedEntities 
          = set.Where(e => getParentID(e) == parentID && !currentIDs.Contains(getID(e)));

        foreach (var toAdd in newEntities)
        {
            set.Add(toAdd);
        }

        foreach (var toDelete in deletedEntities)
        {
            var entity = set.Find(getID(toDelete));
            set.Remove(entity);
        }

        foreach (var toUpdate in existingEntities)
        {
            var entity = set.Find(getID(toUpdate));
            updateSingleEntity(toUpdate, entity);
        }
    }

我想这样使用此功能:

   update(set, parentID, someList, e => e.ID != 0, e => e.ID, e => ParentID, somefunc);

IMO非常整洁。有什么办法可以实现这样的功能?

我做不到(我尝试过):

具有ID属性的接口可以整齐。但是我无法parentID在此接口中定义,因为该属性的名称在DB中的实体周围有所不同。

乔塔贝

首先,正如您在评论中告诉您的那样,您需要使用Expression<Func<TEntity,int>> getId

要使用它,请勿执行此操作,entities.Select(e => getID(e))而只需执行this即可entities.Select(getID)原因是Select需要一个lamba表达式,并且getId包含lambda表达式。Expression<>是必需的,因此它是EF工作所需的表达式树,而不是已编译的表达式。您可以阅读以获取更多信息

对于接口的替代解决方案,您必须像这样实现它:

public interface IId
{
   public int GetId();
}

然后,您需要在所有类中实现它,例如:

public int GetId() { return parentId; }

或者

public int GetId() { return parentId; }

您还应该将接口约束添加到通用方法中,如下所示: where TEntity: class ,IId

但是,您会发现两个问题:

  1. 您将需要GetId对所有实体类型(或至少对于将与thid方法一起使用的那些实体类型)实施
  2. GetId函数无法转换为表达式树,因此EF不知道如何将其转换为SQL表达式。(我不确定,但是它甚至可能会引发错误)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章