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
是只读的。
不,你不能那样做。如果使用代码优先,则模型由代码定义。如果您的代码显示属性是long
,则不会将其映射为数据库中的NUMBER()
列。
我能想到的唯一直接解决方法是您提到的,但您想避免的解决方法。
你仍然可以使用映射器,如自动映射器(此处的详细信息),它允许你从 EF 实体映射到域实体。根据代码的实现方式,这可能会起作用,但是,如果将 EF LINQ 功能泄漏到域逻辑,则这将不起作用。您可以尝试使用AutoMapper IQueryable Extension,但我不确定它们是否适用于您的用例。