1

这一行给了我'TypeAs' 表达式,其输入类型为 User 并且不支持检查 SoftDeleteEntity 类型

var test = this.partiallyFiltered.Where(additionalFilter).ToList();

这是里面的东西。partialFiltered 的类型是IQueriable<User>。附加过滤器是类型Expression<Func<User, bool>>,并且传递的实际表达式(根据调试器)是!((x as SoftDeleteEntity).IsDeleted). 用户继承 SoftDeleteEntity。我认为我没有遗漏任何相关信息,但如果我知道,我会详细说明。我知道必须有一个隐式转换在某处不起作用但我找不到它。

编辑:这是表达式的声明,所有实体都是 IEntity。

public static Expression<Func<TEntity, bool>> DefaultFilter<TEntity>()
        where TEntity : IEntity
{
   if (typeof(SoftDeleteEntity).IsAssignableFrom(typeof(TEntity)))
      return x => !(x as SoftDeleteEntity).IsDeleted;
   else return x => true;
}
4

2 回答 2

3

不幸的是,您将不得不动态地执行此操作。泛型(结合实体框架对类型转换的明显恐惧)不允许您以静态方式编写所需的代码。所以试试这个:

using System.Linq.Expressions;

public static Expression<Func<TEntity, bool>> DefaultFilter<TEntity>()
    where TEntity : IEntity
{
   if (typeof(SoftDeleteEntity).IsAssignableFrom(typeof(TEntity)))
      return DefaultFilterSoftDelete<TEntity>();
   else return x => true;
}

public static Expression<Func<TEntity, bool>> DefaultFilterSoftDelete<TEntity>()
    where TEntity : IEntity
{
    var parameterExpression = Expression.Parameter(typeof(TEntity));
    var propertyExpression = Expression.Property(parameterExpression,
        "IsDeleted");
    var notExpression = Expression.Not(propertyExpression);
    var lambdaExpression = Expression.Lambda<Func<TEntity, bool>>(notExpression,
        parameterExpression);

    return lambdaExpression;
}

这段代码所做的是动态生成您正在寻找的表达式,而无需表达类型转换;User当实体框架遍历该表达式时,它已经被强类型化为特定的实体类型(如)。

编辑:至于为什么代码曾经工作,唯一危险的解释是在代码停止按预期工作之前,您在DefaultFilter函数中创建的 lambda 表达式仅在客户端上运行,而不是由实体框架转换为 SQL。在此过程中,使用过滤器表达式的代码开始将其应用于IQueryable<T>表示实体集合,而不是IEnumerable<T>内存中的(或类似的)集合。您提供的代码可以使用 LINQ to Objects 正常工作,但不能使用实体框架。

于 2013-06-21T20:13:37.267 回答
1

所以我想出了答案,灵感来自亚当的答案。我想出的解决方案如下:

var function = additionalFilter.Compile();
var test = this.partiallyFiltered.Where(x => function(x));

每个实体类型只使用一次此代码,因此在这里编译它似乎不是问题。与其他建议的解决方案相比,这似乎是不太麻烦的解决方案或需要较少重复的解决方案,因此我将在 2 天内接受它,除非其他人提出我的代码曾经工作时间最长的真正原因停止工作。这段代码有效,但它没有解释任何内容,Adam 的解释非常有道理,除了我的静态定义的过滤器之前工作过,而且我可以从我的历史中看到它的代码从未被修改过。只有我的模型被修改了。

编辑:正如亚当斯所指出的,编译的过滤器不会被翻译成sql(我在想什么),因此只会在本地运行,所以这毕竟不是答案

于 2013-06-21T20:54:28.960 回答