2013-09-04 8 views
6

Ich baue eine dynamische Klasse mit Reflektion und Typ Builder und alle, ich möchte wissen, wie kann ich direkt Typ Gießen zu C# TypVerfügt das Entity Framework über ein Dienstprogramm, mit dem DB-Typ in C# -Typ konvertiert wird?

derzeit auf diese Weise mache ich tun, aber macht diese Art der Sache von EF zur Verfügung gestellt?

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)); 

dank

UPDATE i annehmen, dass es kein Nutzen von EF bis jetzt vorgesehen ist, die öffentlich akzeptiert accessible.the Antwort hat nichts mit Ef zu tun. ziemlich unterschiedliche Bibliothek dort.

Ryszard Dżegan Antwort gegeben hat, aber es kann nicht außerhalb TT-Vorlagen oder edmx verwendet werden (oder sein kann, weiß ich nicht)

+1

Haben Sie darüber nachgedacht mit einem 'Dictionary 'anstelle einer switch-Anweisung? –

+0

ys aber ich möchte einige innere Anbieter von EF verwenden, die das Ding tut .. ich will diesen Schalter und Fällen nicht ... –

+1

Nun, ich weiß nichts von EF, aber ich würde definitiv sagen, dass ein Wörterbuch wäre sauberer als Schalter/Gehäuse. –

Antwort

4

Ich weiß nicht, solch eine öffentliche Methode (ich glaube, da ist keiner ... es, das zu uncompile SqlMetal.exe als Antwort akzeptiert)

jedoch versuchen können, können Sie eine gute Vorstellung davon, wie Standard-Verbände haben intern implementiert sind:

In der Klasse LinqToSqlShared.Utility.DbTypeSystem (interne Klasse) Sie können die Methode finden:

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); 
} 

bearbeiten:

  • Siehe this als Referenz

  • Es gibt auch ein Verfahren static SqlDbType Parse(string stype) in der gleichen Klasse, die eine ENUM SqlDbType von SQL-Typ string Definition zurückgibt.

+0

danke für mich auf sqlmetal, aber mein Punkt ist, dass ich String Darstellung des Datenbanktyps aus information_schema Tabelle wie nvarchar, bit, varchar usw. haben. Diese Methode akzeptiert sqldbtype als ein Argument, das ich nicht kenne .. es muss Sei etwas in EF, das macht das schön, ich muss das dekompilieren. –

+0

Ich erwähnte die Funktion, die String-DB-Typ zu SqlDbType enum auch konvertiert. Ich kann es in Antwort einschließen, wenn Sie wünschen :) – Olivier

2

kann ich davon ausgehen, dass da Entity Framework können Mappings zwischen Begriffsmodell und Speichermodell zu schaffen, es interne Fähigkeit hat, jede Datenbank Typen entsprechende konzeptionelle Art zu werfen.

Darüber hinaus verwendet Entity Framework Hilfsklassen, die im Header EF.Utility.CS.ttinclude in seinen T4-Vorlagen vorhanden sind, um Kontext- und Entitätsquelldateien zu generieren.

EF.Utility.CS.ttinclude wiederum verwendet intern Klassen von System.Data.Metadata.Edm Namespace, insbesondere PrimitiveTypeKind Enumeration, die konzeptionelle Typen abdecken und eine Brücke zwischen Datenbanktypen und CLR-Typen bilden.

Wert von PrimitiveTypeKind Enumeration kann in PrimitiveType Class als Eigentum zu finden, und diese Klasse hat eine weitere interessante Eigenschaft namens ClrEquivalentType, die als System.Type erwarteten Renditen.

PrimitiveType Class Instanzen können auf verschiedene Arten abgerufen werden. In T4-Vorlagen arbeitet Entity Framework mit EdmItemCollection Class, das GetPrimitiveTypes Method hat.

In T4-Vorlagen ist der einfachste Weg, auf EdmItemCollection Class zuzugreifen, die CreateEdmItemCollection-Methode von MetadataLoader (aus EF.Utility.CS.ttinclude), die als Parameterpfad zur EDMX-Datei führt.

In tt Datei, könnten Sie schreiben:

<#@ 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#> 
<# 
} 
#> 

Das Ergebnis wird:

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 

Im Klar C# -Code, könnten Sie gleiche tun, wenn Sie MetadataLoader haben würde. Um dieses Hindernis zu umgehen, kopieren Sie einfach die MetadataLoader-Klasse in Ihren Code. Es gibt jedoch auch andere Möglichkeiten, das Ziel zu erreichen. Wenn Sie mit dem Code First-Ansatz arbeiten, ist die interessante Lösung, EdmxWriter.WriteEdmx Method (DbContext, XmlWriter) zu verwenden, um edmx-Datei dynamisch in MemoryStream zu erstellen und dann diesen Stream als Argument in XmlReader.Create Method (Stream) und schließlich XML-Leser als Eingabeparameter in EdmItemCollection Constructor (IEnumerable) zu verwenden.

Es gibt auch Methoden CLR-Typen von C# Typen (Nullable <System.Int32> ==> int?), Aber es ist eine andere Geschichte ...

+0

ich arbeite an dbfirst Ansatz –

+0

Wenn Sie EDMX-Datei haben, wird Ihre Arbeit einfacher dann :) Wenn nicht, können Sie es in Speicher-Stream generieren, wie ich Ihnen gezeigt habe. –