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

如何在LINQ查询中实现CAST(ISNULL(字段,0) AS decimal(18,3))等效逻辑

解决方案

你可以通过投影查询(Select) 实现和原SQL完全一致的转换逻辑,这种方式不会加载多余字段,性能和原生SQL一致:

// 如果你需要返回和原查询一致的OwnerData实体,直接在Select中映射即可
var data = await _context.Set<OwnerProfile>()
    .Where(x => x.ThirdPartyRefId == ownerProfileId)
    .Select(x => new OwnerData
    {
        OwnerProfileId = x.OwnerProfileId,
        Email = x.Email,
        // 对应 CAST(ISNULL([OWB].[CustomBalance], 0) AS decimal(18, 3))
        CustomBalance = Math.Round(x.OwnerBalance.CustomBalance ?? 0m, 3)
    })
    .ToListAsync();

说明:

  • ?? 0m 对应SQL中的ISNULL逻辑,当CustomBalance为null时默认返回0
  • Math.Round(xxx, 3) 会被EF Core自动翻译为对应数据库的精度处理逻辑,最终生成的SQL会自带CAST(xxx AS decimal(18,3))的等价转换
  • 如果你的OwnerBalances是1对多导航属性,调整为取对应单条记录即可:
    CustomBalance = Math.Round(x.OwnerBalances.FirstOrDefault()?.CustomBalance ?? 0m, 3)
    

注:如果你使用的是EF6而非EF Core,将Math.Round替换为DbFunctions.Round即可正常翻译为SQL。


如果你需要严格指定精度为decimal(18,3),可以在实体模型配置中添加精度声明,EF会在查询和映射时自动适配:

// 在DbContext的OnModelCreating方法中添加
modelBuilder.Entity<OwnerData>()
    .Property(p => p.CustomBalance)
    .HasPrecision(18, 3);

如果你一定要保留Include加载全量导航属性的写法,可以在内存中做转换(性能略低,不推荐):

var rawData = await _context.Set<OwnerProfile>()
    .Include(x => x.OwnerBalances)                
    .Where(x => x.ThirdPartyRefId == ownerProfileId)
    .ToListAsync();

var data = rawData.Select(x => new OwnerData
{
    OwnerProfileId = x.OwnerProfileId,
    Email = x.Email,
    CustomBalance = Math.Round(x.OwnerBalances.FirstOrDefault()?.CustomBalance ?? 0m, 3)
}).ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:21:02