Does Entity Framework provide a utility that converts a DB type to a C # type?

im building a dynamic class using reflection and type builder and that’s all, I want to know how I can do direct type casting to C # type

I am currently doing this method, but is it doing something provided by EF?

case "uniqueidentifier": return typeof(Guid); case "bit": return typeof(Boolean); case "nvarchar": return (typeof(string)); case "datetime": return typeof(DateTime); case "float": return typeof(double); case "int": return (typeof(int)); 

thanks

UPDATE I believe that so far there is no utility provided by EF that is publicly available. The answer accepted has nothing to do with Ef. there was a rather different library.

Ryszard Dżegan gave the answer, but it cannot be used outside TT templates or edmx (or maybe I did not know)

+6
source share
2 answers

I do not know such a public method (I think not ... it can be taken as an answer)

However, try unpacking sqlmetal.exe, you can have an idea of ​​how internal associations are implemented internally:

In the LinqToSqlShared.Utility.DbTypeSystem class (inner class) you can find a way:

 internal static Type GetClosestRuntimeType(SqlDbType sqlDbType) { switch (sqlDbType) { case SqlDbType.BigInt: return typeof(long); case SqlDbType.Binary: case SqlDbType.Image: case SqlDbType.Timestamp: case SqlDbType.VarBinary: return typeof(Binary); case SqlDbType.Bit: return typeof(bool); case SqlDbType.Char: case SqlDbType.NChar: case SqlDbType.NText: case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.VarChar: return typeof(string); case SqlDbType.DateTime: case SqlDbType.SmallDateTime: case SqlDbType.Date: case SqlDbType.DateTime2: return typeof(DateTime); case SqlDbType.Decimal: case SqlDbType.Money: case SqlDbType.SmallMoney: return typeof(decimal); case SqlDbType.Float: return typeof(double); case SqlDbType.Int: return typeof(int); case SqlDbType.Real: return typeof(float); case SqlDbType.UniqueIdentifier: return typeof(Guid); case SqlDbType.SmallInt: return typeof(short); case SqlDbType.TinyInt: return typeof(byte); case SqlDbType.Xml: return typeof(XElement); case SqlDbType.Time: return typeof(TimeSpan); case SqlDbType.DateTimeOffset: return typeof(DateTimeOffset); } return typeof(object); } 

change

  • See this for reference.

  • There is also a static SqlDbType Parse(string stype) method in the same class that returns an SqlDbType enumeration from a string definition of type sql.

+4
source

I can assume that, since the Entity Framework is capable of creating mappings between the conceptual model and the storage model, it has the internal ability to apply each type of database to the corresponding conceptual type.

In addition, the Entity Framework uses the helper classes that exist in the EF.Utility.CS.ttinclude header in their T4 templates to generate context and entity source files.

EF.Utility.CS.ttinclude, in turn, internally uses classes from System.Data.Metadata.Edm Namespace , in particular PrimitiveTypeKind Enumeration , which encompasses conceptual types and represents a bridge between database types and CLR types.

The value of PrimitiveTypeKind Enumeration can be found as a property in the PrimitiveType Class , and this class has another interesting ClrEquivalentType property, which is expected to return System.Type .

Primitive Class types can be extracted in various ways. In T4 templates, the Entity Framework works with the EdmItemCollection Class , which is the GetPrimitiveTypes Method .

In T4 templates, the easiest way to access the EdmItemCollection Class is to use the MetadataLoader (from EF.Utility.CS.ttinclude) CreateEdmItemCollection method, which takes edmx as the path to the file.

In the tt file you can write:

 <#@ template hostSpecific="true" #> <#@ output extension=".txt" #> <#@ include file="EF.Utility.CS.ttinclude" #><# var edmxPath = "NorthwindModel.edmx"; // <--- Put the path to your model here. var loader = new MetadataLoader(this); var edmItemCollection = loader.CreateEdmItemCollection(edmxPath); var primitiveTypes = edmItemCollection.GetPrimitiveTypes(); #> <# foreach (var primitiveType in primitiveTypes) { #> <#= primitiveType#> ==> <#= primitiveType.ClrEquivalentType#> <# } #> 

The result will be:

 Edm.Binary ==> System.Byte[] Edm.Boolean ==> System.Boolean Edm.Byte ==> System.Byte Edm.DateTime ==> System.DateTime Edm.Decimal ==> System.Decimal Edm.Double ==> System.Double Edm.Guid ==> System.Guid Edm.Single ==> System.Single Edm.SByte ==> System.SByte Edm.Int16 ==> System.Int16 Edm.Int32 ==> System.Int32 Edm.Int64 ==> System.Int64 Edm.String ==> System.String Edm.Time ==> System.TimeSpan Edm.DateTimeOffset ==> System.DateTimeOffset Edm.Geometry ==> System.Data.Spatial.DbGeometry Edm.Geography ==> System.Data.Spatial.DbGeography Edm.GeometryPoint ==> System.Data.Spatial.DbGeometry Edm.GeometryLineString ==> System.Data.Spatial.DbGeometry Edm.GeometryPolygon ==> System.Data.Spatial.DbGeometry Edm.GeometryMultiPoint ==> System.Data.Spatial.DbGeometry Edm.GeometryMultiLineString ==> System.Data.Spatial.DbGeometry Edm.GeometryMultiPolygon ==> System.Data.Spatial.DbGeometry Edm.GeometryCollection ==> System.Data.Spatial.DbGeometry Edm.GeographyPoint ==> System.Data.Spatial.DbGeography Edm.GeographyLineString ==> System.Data.Spatial.DbGeography Edm.GeographyPolygon ==> System.Data.Spatial.DbGeography Edm.GeographyMultiPoint ==> System.Data.Spatial.DbGeography Edm.GeographyMultiLineString ==> System.Data.Spatial.DbGeography Edm.GeographyMultiPolygon ==> System.Data.Spatial.DbGeography Edm.GeographyCollection ==> System.Data.Spatial.DbGeography 

In simple C # code, you can do the same if you had MetadataLoader. To omit this obstacle, you can simply copy the MetadataLoader class into your code. However, there are other ways to achieve the goal. If you are working with the Code First approach, an interesting solution is to use the EdmxWriter.WriteEdmx Method (DbContext, XmlWriter) to dynamically create an edmx file in a MemoryStream , then put this stream as an argument in the XmlReader.Create Method (Stream) and finally use xml-reader as an input parameter to the EdmItemCollection Constructor (IEnumerable) .

There are also methods for replacing CLR types with C # types (Nullable <System.Int32> ==> int?), But that's another story ...

+2
source

Source: https://habr.com/ru/post/953122/


All Articles