我的EF代码优先应用程序必须与SQL Server和Oracle一起使用。
- 在Oracle中,没有Guid类型,因此它们存储为
nvarchar2(38)
- 在SQL Server中,有一个GUID类型,因此没有问题
是否有一种方法可以全局覆盖Oracle实体框架提供程序的行为,从而使数据库中映射到我的POCO类中的Guid类型的任何列都可以具有自定义转换行为?
现在有些人可能会说,"不要在Oracle中将Guid存储为字符串!请使用RAW(16),因为EF可以很好地处理它"。不幸的是,这不是一个选择。
我可以"教"实体框架如何将字符串数据库值转换为Guid吗?
更新
我刚刚发现了这个链接,这表明该功能不是EF6的原生功能,但可能会在未来的版本中推出。
此外,我不喜欢通过映射私有属性来定制转换器,如所示
更新
这是"从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贡献的一篇帖子,建议你可以改变System.Convert.ChangeType()的行为,它被Oracle数据访问提供商调用
我从未找到解决方案。除非有不同版本的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()格式,并像Chris1804055在他的回答中提到的那样对Guid.Passe()执行检索值的格式。
C#有一个内置的GUID类,您可能需要考虑使用它。https://msdn.microsoft.com/en-us/library/system.guid%28v=vs.110%29.aspx
然后,当你需要将类插入数据库时,你可以GUID.ToString(),也可以通过GUID.Parse(GUID)创建一个GUID。我可能需要一些技巧,但它应该对你有用。
就外汇基金而言。我已经有一段时间没有使用它了,但你可能想把Generated改为code来工作。或者实现自定义类或属性以更新/更改GUID