【问题标题】:Unable to convert Number(1,0) to bool无法将 Number(1,0) 转换为 bool
【发布时间】:2017-02-08 06:27:53
【问题描述】:

我正在使用 Oracle 托管数据访问组件 代码优先

尝试将 Int16 转换为布尔值 但总是收到异常

''class name' 上的'property name' 属性不能设置为 'System.Int16' 值。您必须将此属性设置为非空值 'System.Boolean'

如果我的 POCO 中有一个布尔值作为属性并使用 DbSet 的 SqlQuery 或手动创建数据读取器,我会收到强制转换异常

有趣的是,如果我使用普通的 EF,例如

var test = dbContext.Set<Person>().Where(c=> 1==1).ToList();

不抛出异常,并设置预期的属性值。

一个基本模型

public class Person
{
   [Key]
   public int Id { get; set; }
   public bool Active { get; set; }
}

调用 ToList 引发异常

static void Main(string[] args)
{
     var dbContext = new Context();
     var sql = "select 1 Id, cast(1 as Number(1,0)) Active from dual";
     var query = dbContext.Set<Person>().SqlQuery(sql);
     var list = query.ToList();
}

我在我的配置文件中定义了 edmMappings(我认为这并不重要),如下所示:

<oracle.manageddataaccess.client>
    <version number="*">
      <edmMappings>
        <edmNumberMapping>

          <add NETType="bool" MinPrecision="1" MaxPrecision="1" DBType="Number" />
          <add NETType="byte" MinPrecision="2" MaxPrecision="3" DBType="Number" />
          <add NETType="int16" MinPrecision="4" MaxPrecision="5" DBType="Number" />
          <add NETType="int32" MinPrecision="6" MaxPrecision="10" DBType="Number" />
          <add NETType="int64" MinPrecision="11" MaxPrecision="19" DBType="Number" />
        </edmNumberMapping>
      </edmMappings>
    </version>
  </oracle.manageddataaccess.client>

我的最终目标是避免修改我的 POCO

【问题讨论】:

  • 不确定为什么您会期望从整数自动转换为布尔值?要么将数据库列设为布尔值,要么将类属性设为整数。
  • 我的oracle版本不支持布尔值,不知道有没有版本支持

标签: c# oracle entity-framework-6


【解决方案1】:

也许你可以如下声明你的实体类来实现你所需要的

public class Person
{
   [Key]
   public int Id { get; set; }
   public int Active { get; set; }
   [NotMapped]
   public bool IsActive 
   {
       get { return Convert.ToBoolean(Active); }
       set { Active = Convert.ToInt32(value); }
   }
}

希望这会有所帮助。

【讨论】:

  • 我的最终目标是避免修改模型,或者至少修改我的类的签名。遗憾的是,Oracle 的托管提供商未能意识到这一缺点。
  • 是自动生成的类吗?这就是您要避免修改模型的真正原因吗?
  • 我的课程是手动创建的。我已经分别用 TableAttribute、ColumnAttribute 装饰了每个类和属性
  • 我明白了。可能我们可以在映射时使用 TypeConverters 进行自动转换,而无需如上所述的额外属性。太糟糕了,EF 不支持它们。
【解决方案2】:

因为在 oracle 中不存在布尔值,你可以在你的类中做这样的事情。

public class Person
{
    [Key]
    public int Id { get; set; }
    public bool Active {
        get { return Convert.ToBoolean(activeNumeric); }
        set { this.activeNumeric = Convert.ToInt32(value); }
    }
    private int activeNumeric { get; set; }
}

【讨论】:

  • 这是一个改进
  • @user1555297 你认为这会有帮助吗?
  • 我的模型都装饰如下[Table("Persons")] public class Person { [Key, Column("PERSON_ID")] public int Id{get;set;} [Column("ACTIVE")] public bool Active{get;set;} } 如果我按照您的建议使用额外的私有字段,它会破坏我现有的数据模型,因为调用 SqlQuery 是一种一次性的场景,不会被使用经常
  • 你可以用notmapped声明
  • 我进一步研究了使用私有字段来完成工作。尽管它运行它并没有设置“activeNumeric”字段。该值始终为假。查询运行 = "select 1 Id, cast(1 as Number(1,0)) activeNumeric from dual"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 2019-01-17
  • 1970-01-01
相关资源
最近更新 更多