【问题标题】:Entity Framework: Map a Guid property in C# to a Database String实体框架:将 C# 中的 Guid 属性映射到数据库字符串
【发布时间】: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。现在添加一个包含模型中所有重要属性的接口和一个 Guid Id 属性。最后,在您从任一上下文中使用任一模型之前,请转换到此接口。

标签: c# oracle entity-framework converter


【解决方案1】:

我从来没有找到解决办法。除非有不同版本的 Oracle EF 提供程序支持这一点,否则解决方案是将代表您的 guid 的事物的字符串属性映射到数据库中的字符串。我是这样做的

class Thing { [Required] [StringLength(38)] //38 is the length of a guid with curlies on it public string GuidID { get; set;} }

然后我只是确保在存储新值时为 guid 执行相同的 ToString() 格式,并确保 Guid.Parse() 用于检索他的回答中提到的 Chris1804505 的值。

【讨论】:

    【解决方案2】:

    C# 有一个内置的 GUID 类,您可能需要考虑使用它。 https://msdn.microsoft.com/en-us/library/system.guid%28v=vs.110%29.aspx

    然后,当您需要将类插入数据库时​​,您可以使用 GUID.ToString() 并通过 Guid.Parse(GUID) 创建一个 guid。 我可能需要一点技巧,但它应该对你有用。

    就 EF 而言。自从我使用它已经有一段时间了,但是您可能希望将 Generated 更改为 code 以使其工作。或者实现自定义类或属性来更新/更改 GUID

    【讨论】:

    • 我正在使用 guid。试图弄清楚 EF 如何将 db 字符串转换为 c# guid。寻找此配置如何工作的具体示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 2010-10-14
    • 2011-11-18
    • 2015-01-22
    相关资源
    最近更新 更多