Entity Framework Core 2.0映射int到SQL Server smallint查询报错
解决EF Core 2.0中int属性映射到smallint字段的类型不匹配问题
你遇到的问题是EF Core 2.0在类型匹配上的严格性导致的——它默认不会自动在int(System.Int32)和smallint(System.Int16)之间转换,所以读取数据库值时会抛出类型不匹配的异常。下面提供两种符合你需求的解决方案,不用修改实体属性的int类型:
方案1:升级到EF Core 2.1+(推荐,更优雅)
EF Core 2.1及以上版本引入了Value Converter特性,可以直接在映射配置中添加类型转换逻辑,无需修改实体类:
protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<Tag>() .Property(m => m.Count) .HasColumnType("smallint") // 添加双向转换器:int转short存入数据库,short转int读取 .HasConversion( valueToStore => (short)valueToStore, storedValue => (int)storedValue ); }
这个转换器会自动处理读写时的类型转换,完全透明,你不需要在业务代码里额外写转换逻辑。
方案2:在EF Core 2.0中使用私有字段包装(无需升级)
如果你必须留在EF Core 2.0版本,可以用私有字段+公共int属性的方式,让EF映射底层的short字段,对外暴露int属性:
实体类修改:
public class Tag { // 私有short字段,用于EF映射到数据库的smallint private short _count; // 对外暴露的int属性,自动处理类型转换 public int Count { get => _count; set { // 可选:添加范围校验,避免超出short的取值范围(-32768到32767) if (value < short.MinValue || value > short.MaxValue) throw new ArgumentOutOfRangeException(nameof(value), "Count值超出smallint的范围"); _count = (short)value; } } // 其他属性... }
DbContext映射配置:
protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<Tag>() // 映射私有字段_count到数据库的Count字段,类型为smallint .Property("_count") .HasColumnType("smallint") .HasColumnName("Count"); }
这种方式下,EF会直接操作底层的_count字段(short类型),而业务代码只需要和Count(int类型)交互,不需要额外转换代码。
注意事项
- 不管用哪种方案,都要确保
Count的取值在smallint的范围内(-32768到32767),否则会抛出溢出异常。如果业务中可能超出这个范围,还是建议把数据库字段改成int类型更稳妥。
内容的提问来源于stack exchange,提问作者MikeT
相关产品推荐
相关产品推荐

