【发布时间】:2015-07-09 08:37:53
【问题描述】:
我的 EF 代码优先应用程序必须与 SQL Server 和 Oracle 一起使用。
- 在 Oracle 中,没有 Guid 类型,因此它们存储为
nvarchar2(38)。 - 在 SQL Server 中,有 GUID 类型,所以没有问题。
有没有办法全局覆盖 Oracle 实体框架提供程序的行为,以便数据库中映射到我的 POCO 类中 Guid 类型的任何列都可以具有自定义转换行为?
现在有些人可能会说,“不要在 Oracle 中将 Guid 存储为字符串!改用 RAW(16),因为 EF 可以很好地处理它”。不幸的是,这不是一个选项。
我可以“教”实体框架如何将字符串数据库值转换为 Guid 吗?
更新
我刚刚找到 this 链接,这表明该功能不是 EF6 的原生功能,但可能会在未来的版本中提供。
另外,我不希望通过映射私有属性来自定义转换器,如 here 所示
更新
这是“从'System.String'到'System.Guid'的无效转换”异常的堆栈跟踪
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Oracle.DataAccess.Client.OracleDataReader.ChangeType(Object sourceValue, Type targetType)
at Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader1.GetUntypedValueDefault(DbDataReader reader, Int32 ordinal)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader1.GetValue(DbDataReader reader, Int32 ordinal)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling[TColumn](Int32 ordinal)
at lambda_method(Closure , Shaper )
at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator1.ReadNextElement(Shaper shaper)
我发现 Asad 为 here 贡献的一篇帖子建议您可以更改 Oracle 数据访问提供程序调用的 System.Convert.ChangeType() 的行为
【问题讨论】:
-
是的,在将 LINQ 表达式转换为 SQL 时,您可以教 EF 做几件事。您需要编写一个拦截器来执行此操作。
-
为什么sql-server被列为标签?问题内容与sql-server没有任何关系。
-
@ErikPhilips 一定有人编辑过它。我没有将它列为标签。我刚刚删除了它。
-
@Asad 你有什么好的地方可以开始创建拦截器吗?虽然...我没有尝试修改 LINQ to SQL...我只想获取从 Ado Provider 返回的数据类型并告诉它如何将其转换为 guid。目前它试图做一个直接的演员,这是行不通的。
-
@matrixugly 当然。见here。您可以采取的另一种方法是拥有 两个 模型类。 SQLSrv 有一个 Guid
Id属性,而 Oracle 有一个字符串Id。在其各自的上下文中为每个类提供一个映射和 DBSet。现在添加一个包含模型中所有重要属性的接口和一个GuidId属性。最后,在您从任一上下文中使用任一模型之前,请转换到此接口。
标签: c# oracle entity-framework converter