Entity Framework:如何在C#中将Guid属性映射到数据库字符串

4
我的EF Code First应用程序需要与SQL Server和Oracle一起使用。
  • 在Oracle中,没有Guid类型,因此它们被存储为nvarchar2(38)
  • 在SQL Server中,有一个GUID类型,所以没有问题。

是否有一种方法可以全局覆盖Oracle Entity Framework提供程序的行为,使得任何在数据库中映射到POCO类中的Guid类型列都可以具有自定义转换行为?

现在有些人可能会说,“不要将Guid存储为字符串在Oracle中!改用RAW(16),因为EF可以很好地处理它”。不幸的是,在这里这不是一个选项。

我能否“教”Entity Framework如何将字符串数据库值转换为Guids?

更新

我刚刚发现this链接,它表明该功能不是EF6的本机功能,但可能会在未来的版本中发布。

此外,我更喜欢不通过将私有属性映射为自定义转换器来进行操作,如这里所示。

更新

以下是“从'System.String'到'System.Guid'的无效转换”异常的堆栈跟踪:

在System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) 在System.String.System.IConvertible.ToType(Type type, IFormatProvider provider) 在System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) 在Oracle.DataAccess.Client.OracleDataReader.ChangeType(Object sourceValue, Type targetType) 在Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i) 在System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader1.GetUntypedValueDefault(DbDataReader reader, Int32 ordinal) 在System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader1.GetValue(DbDataReader reader, Int32 ordinal) 在System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling[TColumn](Int32 ordinal) 在lambda_method(Closure , Shaper ) 在System.Data.Entity.Core.Common.Internal.Materialization.Coordinator1.ReadNextElement(Shaper shaper)

我发现Asad在这里贡献了一篇帖子,建议您可以更改被Oracle数据访问提供程序调用的System.Convert.ChangeType()的行为。

是的,您可以教 Entity Framework 在将 LINQ 表达式转换为 SQL 时执行多个操作。您需要编写一个拦截器来实现这一点。 - Asad Saeeduddin
为什么sql-server被列为标签?问题的内容与sql-server没有任何关系。 - Erik Philips
@ErikPhilips 一定是有人编辑过了。我没有将它列为标签。我只是将其删除了。 - C. Tewalt
@Asad,你有没有好的地方可以开始创建拦截器?虽然我不想修改LINQ to SQL...但我只是想获取从Ado Provider返回的数据类型,并告诉它如何将其转换为guid。目前它尝试进行直接转换,但这并不起作用。 - C. Tewalt
@Asad,我刚看到了你回答的这篇文章https://dev59.com/XHfZa4cB1Zd3GeqPPkc6#19022931。它建议我可以告诉CLR如何将字符串转换为GUID。EF调用System.Convert.ChangeType()方法,所以也许这是我可以开始的地方。 - C. Tewalt
显示剩余2条评论
2个回答

0
我从来没有找到解决方案。除非有一个不同版本的Oracle EF提供程序支持它,否则解决方案就是将表示您GUID的事物的字符串属性映射到数据库中的字符串。我是这样做的:
class Thing { [Required] [StringLength(38)] //38是带花括号的guid的长度 public string GuidID { get; set;} }
然后我只需确保在存储新值时执行相同的ToString()格式,并且使用Guid.Parse()检索值,正如Chris1804505在他的答案中提到的那样。

-1

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

然后,当您需要将类插入数据库时,可以使用GUID.ToString()并通过Guid.Parse(GUID)创建一个guid。 可能需要一些微调,但应该适合您。

就EF而言。我已经有一段时间没与它一起工作了,但您可能需要更改生成的代码以使其正常工作。或者实现自定义类或属性以更新/更改GUID


我正在使用 GUID。试图弄清楚 EF 如何将数据库字符串转换为 C# GUID。寻找一个具体的示例来说明这个配置是如何工作的。 - C. Tewalt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接