C# .Net EF 6.1 使用object基类作为属性类型无法映射数据库对象问题
问题原因
EF 6 的 SqlQuery<T> 原生不支持映射到 object 类型的属性,因为框架无法自动判断数据库返回字段的类型并完成装箱操作,所以会跳过对 Value 属性的赋值,导致其始终为 null。
解决方案1:分表定义强类型映射类(推荐)
为不同类型的结果表定义对应强类型的中间映射类,查询后手动转换为统一的 Result 对象,代码改动最小也最稳定。
// 定义对应不同表的强类型实体 public class ResultString { public int Id { get; set; } public string Value { get; set; } } public class ResultInt { public int Id { get; set; } public int Value { get; set; } } // 查询时转换为统一Result对象 results.AddRange(context.Database.SqlQuery<ResultString>("SELECT Id, Value FROM ResultStrings") .Select(x => new Result { Id = x.Id, Value = x.Value }) .ToList()); results.AddRange(context.Database.SqlQuery<ResultInt>("SELECT Id, Value FROM ResultInt") .Select(x => new Result { Id = x.Id, Value = x.Value }) .ToList());
解决方案2:直接用SqlDataReader手动映射
如果不想定义多个中间类,可以直接通过底层DataReader读取数据,自行处理类型装箱:
using (var conn = context.Database.Connection) { if (conn.State != System.Data.ConnectionState.Open) conn.Open(); // 读取字符串类型结果表 using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT Id, Value FROM ResultStrings"; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { results.Add(new Result { Id = reader.GetInt32(0), Value = reader.IsDBNull(1) ? null : reader.GetValue(1) }); } } } // 读取int类型结果表,只需修改CommandText即可复用逻辑 using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT Id, Value FROM ResultInt"; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { results.Add(new Result { Id = reader.GetInt32(0), Value = reader.IsDBNull(1) ? null : reader.GetValue(1) }); } } } }
补充说明
如果使用的是EF Core,还可以通过配置属性的值转换实现直接映射,但EF6不支持该特性,优先使用上述两种方案即可。
内容的提问来源于stack exchange,提问作者katbury
相关产品推荐
相关产品推荐

