【发布时间】:2021-04-17 12:38:50
【问题描述】:
设置:
在 MS SQL Server 数据库中(注意:由外部提供商管理,我们无法更改架构)我们有一个可以为空的表列。同时,在我们的实体模型中,我们故意指定映射到该列的属性不可为空(因为我们想完全忽略该属性的所有null 情况,也不想在我们的代码)。
当然,在运行时,当 EF Core 尝试将可空数据映射到不可空属性时,这会在查询执行时导致异常。
因此我们认为,我们可以使用 EF Core 的 HasQueryFilter,它“指定一个 LINQ 谓词表达式,该表达式将自动应用于针对此实体类型的任何查询”。这个想法是,通过使用HasQueryFilter,我们可以忽略映射到该列的属性为空的所有情况。这样,在执行查询时,可以保证在 EF Core 进行映射之前,该列的所有具有空值的行都从结果集中剥离。
这是示例实体配置:
namespace Foo.Bar.Baz
{
public class MyEntity : IEntityTypeConfiguration<MyEntity>
{
public int Id { get; set; }
public int Foo { get; set; }
public void Configure(EntityTypeBuilder<MyEntity> builder)
{
builder.ToTable("myTable");
builder.HasKey(e => e.Id);
builder.HasQueryFilter(e =>
e.Foo != null // <-- ignoring any datasets with Foo being null
);
}
}
}
问题:
当通过例如执行对该实体的查询时...
DbContext.Set<MyEntity>().ToList();
....HasQueryFilter 已执行,但 e.Foo != null 部分似乎已从 SQL 查询的 WHERE 部分中删除,因为 EF Core 的优化机制认为这是一个“始终为真”的表达式。
问题:
任何想法如何强制 EF Core 执行 .HasQueryFilter 的过滤器部分或如何配置实体以实现我们上面描述的内容?
附:请注意,我们知道我们可以添加另一个服务层来执行另一个映射,或者我们可以引入另一个属性来正确映射列。但我们想避免这种情况,并通过实体类型构建器配置透明地处理这种情况。
【问题讨论】:
标签: c# sql-server .net-core linq-to-sql entity-framework-core