【发布时间】:2020-05-03 06:15:25
【问题描述】:
我有一个在多个地方重复的 Linq 表达式。我想集中定义 Linq 表达式并在所有这些地方使用它。这是代码:
public interface ISoftDelete
{
DateTime? DeletedOn { get; set; }
}
public class BaseModel : ISoftDelete
{
public int Id { get; set; }
public DateTime? DeletedOn { get; set; }
}
public class Epic: BaseModel {
}
public class Feature: BaseModel {
}
public class UserStory: BaseModel {
}
public class ProductFocusDbContext : DbContext
{
public ProductFocusDbContext(DbContextOptions<ProductFocusDbContext> options) : base(options) { }
public DbSet<Epic> Epics { get; set; }
public DbSet<Feature> Features { get; set; }
public DbSet<UserStory> UserStories { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Epic
modelBuilder.Entity<Epic>().HasQueryFilter(ExcludeSoftDeleted);
// Feature
modelBuilder.Entity<Feature>().HasQueryFilter(x => x.DeletedOn == null);
// User Story
modelBuilder.Entity<UserStory>().HasQueryFilter(x => x.DeletedOn == null);
}
System.Linq.Expressions.Expression<Func<ISoftDelete, bool>> ExcludeSoftDeleted = (x => x.DeletedOn == null) ;
}
我想用 ExcludeSoftDeleted 替换所有出现的 x => x.DeletedOn == null,但是当我尝试使用上述代码执行此操作时出现以下异常:
InvalidOperationException: 过滤器表达式 'x => (x.DeletedOn == 为实体类型“Epic”指定的 null)' 无效。表达方式 必须接受一个类型的参数 'ProductFocus.Domain.Model.Epic',返回布尔值,可能不包含 对导航属性的引用。
我怎样才能实现它?
【问题讨论】:
-
minimal reproducible example 在这里很有用。
-
好的,我会尝试创建一个分钟。代表。示例
-
我用一个最小的可重现示例更新了我的问题
-
无法重现。我不能复制、粘贴和编译,更别说运行了。理想情况下我想运行它,但至少编译它。请将您的代码复制到一个新的控制台应用程序并让它编译/运行。
-
谢谢@pinkfloydx33,这是我尝试过的,它奏效了。如果您可以抽出一些时间将其作为答案,并且如果可以的话,还请解释一下为什么接口类型不起作用,而我不得不使用具体的类型来制作有效的 Linq 表达式。谢谢!