EF 5.0 Oracle Code 首先将“精度”设置为数字类型

本文关键字:精度 设置 类型 数字 Oracle Code EF | 更新日期: 2023-09-27 18:31:12

与实体框架 5.0 和 ODP.NET 我正在尝试为我现有的 Oracle 数据库构建代码优先的 DbContext。我知道 ODP 不正式支持这种方法,但也许我仍然需要解决的唯一问题有一个解决方法。

我所有的表都有类型 NUMBER(18,0) 的键。这是一个简单的例子:

  • 桌子

    > DESCRIBE T_USER  
    KUSER  NOT NULL NUMBER(18,0)
    
  • 域对象

    public class User
    {  
        public long Id { get; set; }  
        /* ... */  
    }
    
  • 映射配置

    modelBuilder.Entity<User>()
        .ToTable("T_USER");
    modelBuilder.Entity<User>()
        .Property<long>(x => x.Id)
        .IsRequired()
        .HasColumnType("number")
        .HasColumnName("KUSER");
    

我无法指定 Precision 属性,因为只有 DecimalPropertyConfiguration 类 (.属性()) 公开精度和小数位数属性。

结果是所有转换的查询都包含一个精度为 19 位的 CAST AS 编号(Int64 的默认映射),如下所示: 选择 CAST("范围 1"."KUSER" AS 编号(19,0)) AS "C1", /* ... */

在 JOIN 和 WHERE 子句中执行相同的强制转换,对每个查询的性能影响很大。

在 EDMX XML 文件中 - 我已经弃用了它,因为我希望将来不必使用它 -我有这样一句话:

<Property Name="KUSER" Type="number" Nullable="false" Precision="18" />

是否可以在创建 EF 模型后手动设置属性的精度?

或者,也许有一种方法可以扩展 EF 配置类并添加自定义NumberPropertyConfiguration它公开了精度属性。Edm 命名空间是内部的这一事实阻止了我追求后一条道路。

笔记

  • 我不能用 C# decimal 类型表示这些属性,因为我必须重写几乎所有的域层。
  • 我不能添加一个假的long属性来包装一个隐藏的decimal属性,因为long字段需要在 LINQ-to-SQL 查询联接中使用,然后选择

更新

  • PrimitivePropertyConfiguration中添加了对.HasColumnType("number")的调用,但结果是相同的。
  • 通过遍历MetadataWorkspace来改变属性面是否可行?

    (this as IObjectContextAdapter).ObjectContext.MetadataWorkspace
    

  • 我会尽快自己尝试并更新结果。
    MetadataWorkspace是只读的。

EF 5.0 Oracle Code 首先将“精度”设置为数字类型

不,你不能那样做。如果使用代码优先,则模型由代码定义。如果您的代码显示属性是long ,则不会将其映射为数据库中的NUMBER()列。

我能想到的唯一直接解决方法是您提到的,但您想避免的解决方法。

你仍然可以使用映射器,如自动映射器(此处的详细信息),它允许你从 EF 实体映射到域实体。根据代码的实现方式,这可能会起作用,但是,如果将 EF LINQ 功能泄漏到域逻辑,则这将不起作用。您可以尝试使用AutoMapper IQueryable Extension,但我不确定它们是否适用于您的用例。