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

为何EntityFramework Raw SqlQuery从MySQL返回对象为默认值而非真实值?

解决EF SqlQuery返回KeyValuePair全为默认值的问题

我之前也碰到过一模一样的坑,其实核心原因是Entity Framework没法自动把查询结果映射到KeyValuePair<TKey, TValue>这种结构上——一来它的属性名(Key和Value)和你SQL返回的列名(idcall、starttime)不匹配,二来KeyValuePair是不可变的值类型,EF的映射机制对这类类型的支持本来就有限。

下面给你两种靠谱的解决方案:

方案一:自定义DTO类(推荐,更灵活可靠)

先创建一个和查询结果字段对应的DTO类,让EF能正确映射字段,之后再转成你需要的KeyValuePair:

  1. 定义DTO类:
public class CdrQueryResult
{
    // 属性名和SQL列名对应,或者用[Column]特性指定列名
    public long idcall { get; set; }
    public DateTime starttime { get; set; }

    // 如果想让属性名更规范,也可以加特性映射:
    // [Column("idcall")]
    // public long IdCall { get; set; }
    // [Column("starttime")]
    // public DateTime StartTime { get; set; }
}
  1. 修改查询代码,先获取DTO列表再转换:
using (var dbContext = new PartnerEntities())
{
    string sql = @"select idcall, starttime from cdr limit 0,100";
    // 先查询到DTO列表
    var cdrList = dbContext.Database.SqlQuery<CdrQueryResult>(sql).ToList();
    // 转换成KeyValuePair集合
    List<KeyValuePair<long, DateTime>> rowIdVsDates = cdrList
        .Select(item => new KeyValuePair<long, DateTime>(item.idcall, item.starttime))
        .ToList();
}

方案二:修改SQL列别名匹配KeyValuePair属性

直接在SQL里给列起别名,让别名和KeyValuePair的Key、Value属性名完全匹配(注意大小写):

using (var dbContext = new PartnerEntities())
{
    // 把idcall别名设为Key,starttime设为Value
    string sql = @"select idcall as Key, starttime as Value from cdr limit 0,100";
    List<KeyValuePair<long, DateTime>> rowIdVsDates = dbContext.Database.SqlQuery<KeyValuePair<long, DateTime>>(sql).ToList();
}

⚠️ 注意:这种方式依赖EF对值类型的映射支持,部分EF版本可能存在兼容性问题,所以还是方案一更稳妥。

最后再给你两个排查小技巧:

  • 先在MySQL客户端直接执行你的SQL,确认确实有数据返回
  • 检查列名和属性名的大小写匹配(EF映射是大小写敏感的)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:38:10