c# - 在实体配置中使用 EF Core HasQueryFilter 将可为空的数据库列映射到不可为空的属性?
问题描述
设置:
在 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
部分似乎已从WHERE
SQL 查询的部分中删除,因为 EF Core 的优化机制认为它是一个“始终为真”的表达式。
问题:
任何想法如何强制 EF Core 执行过滤器部分.HasQueryFilter
或如何配置实体以实现我们上面描述的内容?
PS 请注意,我们知道我们可以添加另一个服务层来执行另一个映射,或者我们可以引入另一个属性来正确映射列。但我们希望避免这种情况,并通过实体类型构建器配置透明地处理这种情况。
解决方案
看起来 EF 将优化查询过滤器以删除对所需属性的任何非空检查。如果您从属性中删除[Required]
属性并仅使用查询过滤器,它应该可以工作。或者保留该[Required]
属性,以便您可以在运行时使用它,但在模型配置中覆盖它。
builder.Property(e => e.Foo).IsRequired(false);
推荐阅读
- java - 获取列表中文档中的所有字段 - Firestore Java
- angular - Angular:如何处理与环境相关的属性
- shopware - 使用 API 文章创建的文章(产品)未显示在前面
- c# - 替换邮件正文中html页面中的链接
- c++ - boost::program_options 配置文件格式
- html - 将一个 div 从底部滑到另一个具有角度动画的 div 下方
- mysql - 修改密码时Mysql报错1064
- git - Git重置(软)相对于master的所有更改
- geo - 哪里可以免费获得全球城市名称、州/省名称、邮政编码、国家/地区、纬度、经度数据
- erlang - 将 Core Erlang 表单转换为 Erlang 源代码字符串