简体   繁体   中英

Entity Framework: Map a Guid property in C# to a Database String

My EF code first application has to work with SQL Server and Oracle.

  • In Oracle, there is no Guid type, so they are stored as nvarchar2(38) .
  • In SQL Server, there is a GUID type and so there is no problem.

Is there a way to globally override the behavior of the Oracle Entity Framework provider such that any columns in the database that map to Guid types in my POCO classes can have custom conversion behavior?

Now some might say, "Don't store Guids as strings in Oracle! Use RAW(16) instead because EF plays nicely with that". Unfortunately, that is not an option here.

Can I "teach" Entity framework how to convert string database values to Guids?

Update

I just found this link, which suggests that the capability isn't native to EF6, but may be out in future releases.

Also, I prefer not to have custom converters by mapping private properties as shown here

Update

Here's the stack trace from of the "Invalid cast from 'System.String' to 'System.Guid'" exception

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)

I found a post that Asad contributed to here that suggests you can change the behavior of System.Convert.ChangeType() which is getting called by the Oracle Data Access Provider

I never did find a solution. Unless a different version of the Oracle EF provider comes out to support this, the solution is to map the string property of the thing that represents your guid to a string in the db. I did it like this

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

Then I just make sure to do the same ToString() format for guids when storing new values, and Guid.Parse() for retrieving the values as Chris1804505 mentioned in his answer.

C# has a built in GUID Class you may want to think about using that. https://msdn.microsoft.com/en-us/library/system.guid%28v=vs.110%29.aspx

Then when you need to insert the class in to the database you can GUID.ToString() and also create a guid via Guid.Parse(GUID). I may take a little finessing but it should work for you.

As far as EF is concerned. It's been a while since I have worked with it but you will probably want to change the Generated to code to work. Or implement a custom class or property to update/change the GUID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM