You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.2迁移至.NET 6后EF列映射与查询改写问题求助

问题解答

1. 保持EF实体列名与数据库完全一致

EF Core数据库优先生成实体时,默认会采用驼峰命名约定,自动将数据库中的下划线命名(如Topic_Id)转换为PascalCase格式(如TopicId)。要保留数据库的原始列名,只需在Scaffold-DbContext命令中添加--use-database-names参数即可。

修改后的完整命令:

PM> Scaffold-DbContext "Server=(servername);Database=(dbname);MultipleActiveResultSets=true;User ID=usr;Password=pass" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Data/DB -force --use-database-names

该参数会强制EF Core直接复用数据库中的表名、列名,不执行任何命名转换。

2. 避免将查询转换为IEnumerable,优化.NET 6查询代码

你完全不需要将查询转换为IEnumerable——这种写法会把整张表的数据加载到内存后再过滤,严重损耗性能。当前问题源于对EF Core 3.0+查询翻译规则的变化不熟悉,以下是正确的优化方案:

问题根源

  • .NET Core 2.2的EF Core对空值处理较宽松,允许直接调用null对象的方法(如Code.ToLower());但EF Core 3.0+开始严格执行查询翻译,不支持无法转换为SQL的空引用操作。
  • 原代码未显式Include关联导航属性,可能依赖了.NET Core 2.2默认开启的延迟加载;而.NET 6默认关闭了延迟加载,因此需要显式Include或重新开启延迟加载。

正确的.NET 6查询写法(保持IQueryable,数据库端执行)

db.TblUserCredential? UserCredential = this.DbContext.TblUserCredentials
    .Include(x => x.CredentialTypeNavigation) // 显式加载关联属性,开启延迟加载后可省略
    .Where(x => x.CredentialTypeNavigation.Code != null 
                && EF.Functions.Like(x.CredentialTypeNavigation.Code.ToLower(), "%kingsid%"))
    .FirstOrDefault(x => x.Identifier != null 
                         && x.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase));

额外优化建议

  • 开启延迟加载:若希望和.NET Core 2.2一样自动加载关联属性,可在DbContext的OnConfiguring方法中添加:
    optionsBuilder.UseLazyLoadingProxies();
    
    开启后可去掉Include语句,但需注意延迟加载可能引发N+1查询问题,需根据业务场景选择。
  • 使用EF.Functions:EF.Functions.Like会被翻译为SQL的LIKE语句,比内存中执行Contains性能更优;若需忽略大小写,也可直接在SQL层面处理(如LOWER(Code) LIKE '%kingsid%')。
  • 空值检查:EF Core 3.0+要求必须显式处理可能为null的属性,避免查询中出现潜在的空引用异常。

内容的提问来源于stack exchange,提问作者M G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:33:10