Klasse aus Datenbanktabelle generieren


214

Wie kann ich eine Klasse aus einem SQL Server-Tabellenobjekt generieren?

Ich spreche nicht von ORM. Ich muss nur die Entitäten erstellen (einfache Klasse). Etwas wie:

    public class Person 
    {
        public string Name { get;set; }
        public string Phone { get;set; }
    }

Gegeben eine Tabelle wie:

+----+-------+----------------+
| ID | Name  |     Phone      |
+----+-------+----------------+
|  1 | Alice | (555) 555-5550 |
|  2 | Bob   | (555) 555-5551 |
|  3 | Cathy | (555) 555-5552 |
+----+-------+----------------+



14
Lassen Sie Entity Framework die Klassen für Sie generieren, verwenden Sie jedoch nicht die Klassen, die mit dem Datenbankzugriff zu tun haben.
John Saunders

Ich konnte @John Saunders nicht mehr zustimmen. Ich habe es in der Vergangenheit selbst manuell gemacht, aber es ist einfach zu zeitaufwändig. EF macht es in den meisten Fällen gleich beim ersten Mal richtig. Wenn nicht, ist das Optimieren der generierten Klassen viel weniger zeitaufwändig als alles selbst zu tun. Ich habe bessere Dinge mit meiner Zeit zu tun, als Code zu schreiben, den ein ORM-Generator für mich tun kann. Ich verstehe eine Abneigung gegen generierten Code, aber der Kompromiss zwischen Zeit- (und Kosten-) Einsparungen lohnt sich zumindest für mich.
David

4
Ich denke, EF wäre in der Tat die beste Lösung. Eine andere Möglichkeit wäre LINQ to SQL Classes. Sie fügen es einfach Ihrem Projekt hinzu und geben ihm eine Datenbankverbindung. Als nächstes wählen Sie einfach die Tabellen aus, die Sie benötigen, und es werden einige Klassen für Sie erstellt.
Kevin Cloet

2
In der Praxis ist EF nicht immer die beste Lösung. Zum Beispiel könnte es mehrere unerfahrene Entwickler geben, die krasse Änderungen an der edmx-Datei vornehmen, die gelinde gesagt zu Versionskonflikten führen ... Außerdem ist die Option möglicherweise auch nicht immer verfügbar. Zum Beispiel möchte der technische Leiter möglicherweise einfach nicht, dass Sie es aus irgendeinem Grund verwenden.
CarneyCode

Antworten:


683

Setzen Sie @TableName auf den Namen Ihrer Tabelle.

declare @TableName sysname = 'TableName'
declare @Result varchar(max) = 'public class ' + @TableName + '
{'

select @Result = @Result + '
    public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'double'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'string'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'float'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'long'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

set @Result = @Result  + '
}'

print @Result

5
Fügen Sie diesen Code für nullfähige Typen zwischen endund ColumnTypein Alex 'SQL-Skript an. + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END
Betäuben Sie den

6
@AlexAza Sie sollten "when ' float' then 'float'" in " when 'float' then 'double'und" when 'real' then 'double'"in" ändern when 'real' then 'float'. Es scheint, dass Sie diese Typen verwirrt haben. Das C # -Äquivalent zu einem SQL-Float ist ein Double und das C # -Äquivalent zu einem SQL-Real ist ein Float .
Jared Strand

4
Schöne Antwort, aber Sie müssen zu ändern print @Result, print CAST(@Result AS TEXT)sonst wird es auf großen Tabellen abgeschnitten.
Robert McKee

2
Wie wäre es, wenn Sie Datenanmerkungen zur Validierung hinzufügen - z. B. maximale Feldlänge? :)
Niico


72

Ich konnte Alex 'Antwort nicht dazu bringen, an SQL Server 2008 R2 zu arbeiten. Also habe ich es nach den gleichen Grundprinzipien umgeschrieben. Es ermöglicht jetzt Schemata und es wurden mehrere Korrekturen für Zuordnungen von Spalteneigenschaften vorgenommen (einschließlich der Zuordnung von nullbaren Datumstypen zu nullbaren C # -Werttypen). Hier ist das SQL:

   DECLARE @TableName VARCHAR(MAX) = 'NewsItem' -- Replace 'NewsItem' with your table name
    DECLARE @TableSchema VARCHAR(MAX) = 'Markets' -- Replace 'Markets' with your schema name
    DECLARE @result varchar(max) = ''

    SET @result = @result + 'using System;' + CHAR(13) + CHAR(13) 

    IF (@TableSchema IS NOT NULL) 
    BEGIN
        SET @result = @result + 'namespace ' + @TableSchema  + CHAR(13) + '{' + CHAR(13) 
    END

    SET @result = @result + 'public class ' + @TableName + CHAR(13) + '{' + CHAR(13) 

    SET @result = @result + '#region Instance Properties' + CHAR(13)  

   SELECT
      @result = @result + CHAR(13)
      + ' public ' + ColumnType + ' ' + ColumnName + ' { get; set; } ' + CHAR(13)
    FROM (SELECT
      c.COLUMN_NAME AS ColumnName,
      CASE c.DATA_TYPE
        WHEN 'bigint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Int64?'
            ELSE 'Int64'
          END
        WHEN 'binary' THEN 'Byte[]'
        WHEN 'bit' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'bool?'
            ELSE 'bool'
          END
        WHEN 'char' THEN 'string'
        WHEN 'date' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetime' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetime2' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetimeoffset' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTimeOffset?'
            ELSE 'DateTimeOffset'
          END
        WHEN 'decimal' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'float' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Single?'
            ELSE 'Single'
          END
        WHEN 'image' THEN 'Byte[]'
        WHEN 'int' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'int?'
            ELSE 'int'
          END
        WHEN 'money' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'nchar' THEN 'string'
        WHEN 'ntext' THEN 'string'
        WHEN 'numeric' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'nvarchar' THEN 'string'
        WHEN 'real' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Double?'
            ELSE 'Double'
          END
        WHEN 'smalldatetime' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'smallint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Int16?'
            ELSE 'Int16'
          END
        WHEN 'smallmoney' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'text' THEN 'string'
        WHEN 'time' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'TimeSpan?'
            ELSE 'TimeSpan'
          END
        WHEN 'timestamp' THEN 'Byte[]'
        WHEN 'tinyint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Byte?'
            ELSE 'Byte'
          END
        WHEN 'uniqueidentifier' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Guid?'
            ELSE 'Guid'
          END
        WHEN 'varbinary' THEN 'Byte[]'
        WHEN 'varchar' THEN 'string'
        ELSE 'Object'
      END AS ColumnType,
      c.ORDINAL_POSITION
    FROM INFORMATION_SCHEMA.COLUMNS c
    WHERE c.TABLE_NAME = @TableName
    AND ISNULL(@TableSchema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA) t
    ORDER BY t.ORDINAL_POSITION

    SET @result = @result + CHAR(13) + '#endregion Instance Properties' + CHAR(13)  

    SET @result = @result  + '}' + CHAR(13)

    IF (@TableSchema IS NOT NULL) 
    BEGIN
        SET @result = @result + CHAR(13) + '}' 
    END

    PRINT @result

Es erzeugt C # wie folgt:

using System;

namespace Markets
{
    public class NewsItem        {
        #region Instance Properties

        public Int32 NewsItemID { get; set; }

        public Int32? TextID { get; set; }

        public String Description { get; set; }

        #endregion Instance Properties
    }

}

Es kann eine Idee sein, EF, Linq to Sql oder sogar Scaffolding zu verwenden. Es gibt jedoch Zeiten, in denen eine solche Codierung nützlich ist. Ehrlich gesagt mag ich es nicht, EF-Navigationseigenschaften zu verwenden, bei denen der generierte Code 19.200 separate Datenbankaufrufe zum Auffüllen eines 1000-Zeilen-Rasters ausführte. Dies hätte in einem einzigen Datenbankaufruf erreicht werden können. Es kann jedoch auch sein, dass Ihr technischer Architekt nicht möchte, dass Sie EF und dergleichen verwenden. Sie müssen also auf Code wie diesen zurückgreifen ... Übrigens kann es auch eine Idee sein, jede der Eigenschaften mit Attributen für DataAnnotations usw. zu dekorieren, aber ich behalte dies streng POCO.

EDIT Feste für Timestamp und Guid?


+1, das hat auch bei mir gut funktioniert. Ich verwende EF für unsere Hauptdatenbank, muss aber einen Sproc von einer anderen Datenbank abrufen und wollte dafür kein ganzes EF-Projekt codieren. Daher konnte ich schnell eine Klasse erstellen, um meine Sproc-Ergebnismenge aufzunehmen ... danke
Jim Tollan

Ich benutze es jetzt noch, aber ich habe MVC-Eigenschaftsattribute für die Zeichenfolgenlänge usw.
eingefügt

Erzeugt für mich eine leere Klasse ohne Eigenschaften / Spalten.
Highwingers

@highwingers: Verwenden Sie ein gültiges Schema und einen gültigen Tabellennamen? Bitte zeigen Sie mir Ihre Umsetzung der oben genannten.
CarneyCode

Dies ist poliert. Ich benutze das. Aber danke an Alex für die Erstellung des Originals.
Tejasvi Hegde

20

VB-Version

declare @TableName sysname = 'myTableName'
declare @prop varchar(max)
PRINT 'Public Class ' + @TableName
declare props cursor for
select distinct ' public property ' + ColumnName + ' AS ' + ColumnType AS prop
from ( 
    select  
        replace(col.name, ' ', '_') ColumnName,  column_id, 
        case typ.name  
            when 'bigint' then 'long' 
            when 'binary' then 'byte[]' 
            when 'bit' then 'boolean' 
            when 'char' then 'string' 
            when 'date' then 'DateTime' 
            when 'datetime' then 'DateTime' 
            when 'datetime2' then 'DateTime' 
            when 'datetimeoffset' then 'DateTimeOffset' 
            when 'decimal' then 'decimal' 
            when 'float' then 'float' 
            when 'image' then 'byte[]' 
            when 'int' then 'integer' 
            when 'money' then 'decimal' 
            when 'nchar' then 'char' 
            when 'ntext' then 'string' 
            when 'numeric' then 'decimal' 
            when 'nvarchar' then 'string' 
            when 'real' then 'double' 
            when 'smalldatetime' then 'DateTime' 
            when 'smallint' then 'short' 
            when 'smallmoney' then 'decimal' 
            when 'text' then 'string' 
            when 'time' then 'TimeSpan' 
            when 'timestamp' then 'DateTime' 
            when 'tinyint' then 'byte' 
            when 'uniqueidentifier' then 'Guid' 
            when 'varbinary' then 'byte[]' 
            when 'varchar' then 'string' 
        end ColumnType 
    from sys.columns col join sys.types typ on col.system_type_id = typ.system_type_id 
    where object_id = object_id(@TableName) 
) t 
order by prop
open props
FETCH NEXT FROM props INTO @prop
WHILE @@FETCH_STATUS = 0
BEGIN
    print @prop
    FETCH NEXT FROM props INTO @prop
END
close props
DEALLOCATE props
PRINT 'End Class'

aber es gibt kein Get / SET?
Highwingers

1
@highwingers seit Visual Studio 2010, sie sind nicht erforderlich stackoverflow.com/a/460032/618186
guanome

Ich musste den Text "use MyDatabase" oben hinzufügen, um richtig zu arbeiten. Andernfalls würden einige nicht erkennbare Klasseneigenschaften generiert.
Cesar

Sehr schön. Aber floatsollte gehen Double, byte[]umByte()
RichieRich

Schön gemacht. Ich habe sogar eine Aussicht ausprobiert und es hat wie ein Zauber funktioniert!
Hanlet Escaño

14

Ein bisschen spät, aber ich habe ein Web-Tool erstellt, mit dem Sie ein C # -Objekt (oder ein anderes Objekt) aus dem SQL-Ergebnis, der SQL-Tabelle und SQL SP erstellen können.

sql2object.com

Dies kann wirklich sicher sein, dass Sie alle Ihre Eigenschaften und Typen eingeben müssen.

Wenn die Typen nicht erkannt werden, wird die Standardeinstellung ausgewählt.


1
Nicht schlecht, aber es kann kein Tabellendefinitionsskript als Quelle verwenden
Anatol

Das ist großartig :) Es ist großartig, dass es sowohl für Ergebnisse als auch für Tabellen funktioniert. Wäre wirklich schön, wenn Sie es so ändern könnten, dass es einfach alles ignoriert, CREATE TABLEdamit ich alles ausschneiden und einfügen kann. Auch wenn Sie eine Chance bekommen, können Sie dort ein 'Trim ()' hinzufügen - es schlägt fehl, wenn am Anfang eine leere Zeile steht und die Leute es aufgeben. Einfach, wenn Sie wissen, dass Sie es entfernen müssen - aber Sie verlieren Menschen, wenn Sie einen Fehler machen.
Simon_Weaver

Auch was ist das Format für eine SQL-Ergebnismenge. Ich kopiere und füge es einfach aus einem Textausgabefenster ein und es gibt mir ein einziges Feld mit allen Spaltennamen: - / Was ist der Trick?
Simon_Weaver

oder Sie können es Open Source machen und die Community es so aufbauen lassen, wie sie es wollen.
Adil H. Raza

Es wird keine C # -Klasse aus dem Skript "Tabelle erstellen" erstellt.
Mehmet

12

Ich versuche meine 2 Cent zu geben

0) QueryFirst https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst Query-first ist eine Visual Studio-Erweiterung für die intelligente Arbeit mit SQL in C # -Projekten. Verwenden Sie die bereitgestellte SQL-Vorlage, um Ihre Abfragen zu entwickeln. Wenn Sie die Datei speichern, führt Query-first Ihre Abfrage aus, ruft das Schema ab und generiert zwei Klassen und eine Schnittstelle: eine Wrapper-Klasse mit den Methoden Execute (), ExecuteScalar (), ExecuteNonQuery () usw., der entsprechenden Schnittstelle und einer POCO-Kapselung eine Reihe von Ergebnissen.Geben Sie hier die Bildbeschreibung ein

1) Sql2Objects Erstellt die Klasse ausgehend vom Ergebnis einer Abfrage (jedoch nicht der DAL). Geben Sie hier die Bildbeschreibung ein

2) https://docs.microsoft.com/en-us/ef/ef6/resources/tools Geben Sie hier die Bildbeschreibung ein

3) https://visualstudiomagazine.com/articles/2012/12/11/sqlqueryresults-code-generation.aspx Geben Sie hier die Bildbeschreibung ein

4) http://www.codesmithtools.com/product/generator#features


9

Ja, diese sind großartig, wenn Sie ein einfaches ORM wie Dapper verwenden.

Wenn Sie .Net verwenden, können Sie zur Laufzeit mit jedem DataSet mithilfe der WriteXmlSchema-Methode eine XSD-Datei generieren. http://msdn.microsoft.com/en-us/library/xt7k72x8(v=vs.110).aspx

So was:

using (SqlConnection cnn = new SqlConnection(mConnStr)) {
DataSet Data = new DataSet();
cnn.Open();
string sql = "SELECT * FROM Person";

using (SqlDataAdapter Da = new SqlDataAdapter(sql, cnn))
{
try
{
    Da.Fill(Data);
    Da.TableMappings.Add("Table", "Person");
    Data.WriteXmlSchema(@"C:\Person.xsd");
}
catch (Exception ex)
{ MessageBox.Show(ex.Message); }
}
cnn.Close();

Von dort aus können Sie mit xsd.exe eine Klasse erstellen, deren XML über die Eingabeaufforderung des Entwicklers serialisierbar ist. http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

so was:

xsd C:\Person.xsd /classes /language:CS

8

Verwenden Sie diese Option, um NULLABLE-Eigenschaften auszudrucken.
Es fügt eine geringfügige Änderung an Alex Azas Skript für den CASEAnweisungsblock hinzu.

declare @TableName sysname = 'TableName'
declare @result varchar(max) = 'public class ' + @TableName + '
{'

select @result = @result + '
    public ' + ColumnType + ' ' + ColumnName + ' { get; set; }
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end + 
        CASE
            WHEN col.is_nullable=1 AND
                 typ.name NOT IN (
                     'binary', 'varbinary', 'image',
                     'text', 'ntext',
                     'varchar', 'nvarchar', 'char', 'nchar')
            THEN '?'
            ELSE '' END AS [ColumnType]
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id 
    where object_id = object_id(@TableName)
) t
order by column_id

set @result = @result  + '
}'

print @result

5

Ich habe versucht, die obigen Vorschläge zu verwenden, und dabei die Lösungen in diesem Thread verbessert.

Angenommen, Sie verwenden eine Basisklasse (in diesem Fall ObservableObject), die das PropertyChanged-Ereignis implementiert. Sie würden so etwas tun. Ich werde wahrscheinlich eines Tages einen Blog-Beitrag in meinem Blog sqljana.wordpress.com schreiben

Bitte ersetzen Sie die ersten drei Variablen durch die Werte:

    --These three things have to be substituted (when called from Powershell, they are replaced before execution)
DECLARE @Schema VARCHAR(MAX) = N'&Schema'
DECLARE @TableName VARCHAR(MAX) = N'&TableName'
DECLARE @Namespace VARCHAR(MAX) = N'&Namespace'

DECLARE @CRLF VARCHAR(2) = CHAR(13) + CHAR(10);
DECLARE @result VARCHAR(max) = ' '

DECLARE @PrivateProp VARCHAR(100) = @CRLF + 
                CHAR(9) + CHAR(9) + 'private <ColumnType> _<ColumnName>;';
DECLARE @PublicProp VARCHAR(255) = @CRLF + 
                CHAR(9) + CHAR(9) + 'public <ColumnType> <ColumnName> '  + @CRLF +
                CHAR(9) + CHAR(9) + '{ ' + @CRLF +
                CHAR(9) + CHAR(9) + '   get { return _<ColumnName>; } ' + @CRLF +
                CHAR(9) + CHAR(9) + '   set ' + @CRLF +
                CHAR(9) + CHAR(9) + '   { ' + @CRLF +
                CHAR(9) + CHAR(9) + '       _<ColumnName> = value;' + @CRLF +
                CHAR(9) + CHAR(9) + '       base.RaisePropertyChanged();' + @CRLF +
                CHAR(9) + CHAR(9) + '   } ' + @CRLF +
                CHAR(9) + CHAR(9) + '}' + @CRLF;

DECLARE @RPCProc VARCHAR(MAX) = @CRLF +         
                CHAR(9) + CHAR(9) + 'public event PropertyChangedEventHandler PropertyChanged; ' + @CRLF +
                CHAR(9) + CHAR(9) + 'private void RaisePropertyChanged( ' + @CRLF +
                CHAR(9) + CHAR(9) + '       [CallerMemberName] string caller = "" ) ' + @CRLF +
                CHAR(9) + CHAR(9) + '{  ' + @CRLF +
                CHAR(9) + CHAR(9) + '   if (PropertyChanged != null)  ' + @CRLF +
                CHAR(9) + CHAR(9) + '   { ' + @CRLF +
                CHAR(9) + CHAR(9) + '       PropertyChanged( this, new PropertyChangedEventArgs( caller ) );  ' + @CRLF +
                CHAR(9) + CHAR(9) + '   } ' + @CRLF +
                CHAR(9) + CHAR(9) + '}';

DECLARE @PropChanged VARCHAR(200) =  @CRLF +            
                CHAR(9) + CHAR(9) + 'protected override void AfterPropertyChanged(string propertyName) ' + @CRLF +
                CHAR(9) + CHAR(9) + '{ ' + @CRLF +
                CHAR(9) + CHAR(9) + '   System.Diagnostics.Debug.WriteLine("' + @TableName + ' property changed: " + propertyName); ' + @CRLF +
                CHAR(9) + CHAR(9) + '}';

SET @result = 'using System;' + @CRLF + @CRLF +
                'using MyCompany.Business;' + @CRLF + @CRLF +
                'namespace ' + @Namespace  + @CRLF + '{' + @CRLF +
                '   public class ' + @TableName + ' : ObservableObject' + @CRLF + 
                '   {' + @CRLF +
                '   #region Instance Properties' + @CRLF 

SELECT @result = @result
                 + 
                REPLACE(
                            REPLACE(@PrivateProp
                            , '<ColumnName>', ColumnName)
                        , '<ColumnType>', ColumnType)
                +                           
                REPLACE(
                            REPLACE(@PublicProp
                            , '<ColumnName>', ColumnName)
                        , '<ColumnType>', ColumnType)                   
FROM
(
    SELECT  c.COLUMN_NAME   AS ColumnName 
        , CASE c.DATA_TYPE   
            WHEN 'bigint' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int64?' ELSE 'Int64' END
            WHEN 'binary' THEN 'Byte[]'
            WHEN 'bit' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Boolean?' ELSE 'Boolean' END            
            WHEN 'char' THEN 'String'
            WHEN 'date' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetime' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetime2' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetimeoffset' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTimeOffset?' ELSE 'DateTimeOffset' END                                    
            WHEN 'decimal' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                    
            WHEN 'float' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Single?' ELSE 'Single' END                                    
            WHEN 'image' THEN 'Byte[]'
            WHEN 'int' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int32?' ELSE 'Int32' END
            WHEN 'money' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                
            WHEN 'nchar' THEN 'String'
            WHEN 'ntext' THEN 'String'
            WHEN 'numeric' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                            
            WHEN 'nvarchar' THEN 'String'
            WHEN 'real' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Double?' ELSE 'Double' END                                                                        
            WHEN 'smalldatetime' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
            WHEN 'smallint' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int16?' ELSE 'Int16'END            
            WHEN 'smallmoney' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                                        
            WHEN 'text' THEN 'String'
            WHEN 'time' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'TimeSpan?' ELSE 'TimeSpan' END                                                                                    
            WHEN 'timestamp' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
            WHEN 'tinyint' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Byte?' ELSE 'Byte' END                                                
            WHEN 'uniqueidentifier' THEN 'Guid'
            WHEN 'varbinary' THEN 'Byte[]'
            WHEN 'varchar' THEN 'String'
            ELSE 'Object'
        END AS ColumnType
        , c.ORDINAL_POSITION 
FROM    INFORMATION_SCHEMA.COLUMNS c
WHERE   c.TABLE_NAME = @TableName 
    AND ISNULL(@Schema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA  
) t
ORDER BY t.ORDINAL_POSITION

SELECT @result = @result + @CRLF + 
                CHAR(9) + '#endregion Instance Properties' + @CRLF +
                --CHAR(9) + @RPCProc + @CRLF +
                CHAR(9) + @PropChanged + @CRLF +
                CHAR(9) + '}' + @CRLF +
                @CRLF + '}' 
--SELECT @result
PRINT @result

Die Basisklasse basiert auf Josh Smiths Artikel hier. Von http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

Ich habe die Klasse in ObservableObject umbenannt und auch die Funktion ac # 5 mithilfe des CallerMemberName-Attributs genutzt

//From http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
//
//Jana's change: Used c# 5 feature to bypass passing in the property name using [CallerMemberName] 
//  protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace MyCompany.Business
{

    /// <summary>
    /// Implements the INotifyPropertyChanged interface and 
    /// exposes a RaisePropertyChanged method for derived 
    /// classes to raise the PropertyChange event.  The event 
    /// arguments created by this class are cached to prevent 
    /// managed heap fragmentation.
    /// </summary>
    [Serializable]
    public abstract class ObservableObject : INotifyPropertyChanged
    {
        #region Data

        private static readonly Dictionary<string, PropertyChangedEventArgs> eventArgCache;
        private const string ERROR_MSG = "{0} is not a public property of {1}";

        #endregion // Data

        #region Constructors

        static ObservableObject()
        {
            eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
        }

        protected ObservableObject()
        {
        }

        #endregion // Constructors

        #region Public Members

        /// <summary>
        /// Raised when a public property of this object is set.
        /// </summary>
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Returns an instance of PropertyChangedEventArgs for 
        /// the specified property name.
        /// </summary>
        /// <param name="propertyName">
        /// The name of the property to create event args for.
        /// </param>        
        public static PropertyChangedEventArgs
            GetPropertyChangedEventArgs(string propertyName)
        {
            if (String.IsNullOrEmpty(propertyName))
                throw new ArgumentException(
                    "propertyName cannot be null or empty.");

            PropertyChangedEventArgs args;

            // Get the event args from the cache, creating them
            // and adding to the cache if necessary.
            lock (typeof(ObservableObject))
            {
                bool isCached = eventArgCache.ContainsKey(propertyName);
                if (!isCached)
                {
                    eventArgCache.Add(
                        propertyName,
                        new PropertyChangedEventArgs(propertyName));
                }

                args = eventArgCache[propertyName];
            }

            return args;
        }

        #endregion // Public Members

        #region Protected Members

        /// <summary>
        /// Derived classes can override this method to
        /// execute logic after a property is set. The 
        /// base implementation does nothing.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected virtual void AfterPropertyChanged(string propertyName)
        {
        }

        /// <summary>
        /// Attempts to raise the PropertyChanged event, and 
        /// invokes the virtual AfterPropertyChanged method, 
        /// regardless of whether the event was raised or not.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            this.VerifyProperty(propertyName);

            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                // Get the cached event args.
                PropertyChangedEventArgs args =
                    GetPropertyChangedEventArgs(propertyName);

                // Raise the PropertyChanged event.
                handler(this, args);
            }

            this.AfterPropertyChanged(propertyName);
        }

        #endregion // Protected Members

        #region Private Helpers

        [Conditional("DEBUG")]
        private void VerifyProperty(string propertyName)
        {
            Type type = this.GetType();

            // Look for a public property with the specified name.
            PropertyInfo propInfo = type.GetProperty(propertyName);

            if (propInfo == null)
            {
                // The property could not be found,
                // so alert the developer of the problem.

                string msg = string.Format(
                    ERROR_MSG,
                    propertyName,
                    type.FullName);

                Debug.Fail(msg);
            }
        }

        #endregion // Private Helpers
    }
}

Hier ist der Teil, den ihr noch mehr mögen werdet. Ich habe ein Powershell-Skript erstellt, das für alle Tabellen in einer SQL-Datenbank generiert wird. Es basiert auf einem Powershell-Guru namens Chad Millers Cmdlet Invoke-SQLCmd2, das hier heruntergeladen werden kann: http://gallery.technet.microsoft.com/ScriptCenter/7985b7ef-ed89-4dfd-b02a-433cc4e30894/

Sobald Sie dieses Cmdlet haben, wird das für alle Tabellen zu generierende Powershell-Skript einfach (ersetzen Sie die Variablen durch Ihre spezifischen Werte).

. C:\MyScripts\Invoke-Sqlcmd2.ps1

$serverInstance = "MySQLInstance"
$databaseName = "MyDb"
$generatorSQLFile = "C:\MyScripts\ModelGen.sql" 
$tableListSQL = "SELECT name FROM $databaseName.sys.tables"
$outputFolder = "C:\MyScripts\Output\"
$namespace = "MyCompany.Business"

$placeHolderSchema = "&Schema"
$placeHolderTableName = "&TableName"
$placeHolderNamespace = "&Namespace"

#Get the list of tables in the database to generate c# models for
$tables = Invoke-Sqlcmd2 -ServerInstance $serverInstance -Database $databaseName -Query $tableListSQL -As DataRow -Verbose

foreach ($table in $tables)
{
    $table1 = $table[0]
    $outputFile = "$outputFolder\$table1.cs"


    #Replace variables with values (returns an array that we convert to a string to use as query)
    $generatorSQLFileWSubstitutions = (Get-Content $generatorSQLFile).
                                            Replace($placeHolderSchema,"dbo").
                                            Replace($placeHolderTableName, $table1).
                                            Replace($placeHolderNamespace, $namespace) | Out-String

    "Ouputing for $table1 to $outputFile"

    #The command generates .cs file content for model using "PRINT" statements which then gets written to verbose output (stream 4)
    # ...capture the verbose output and redirect to a file
    (Invoke-Sqlcmd2 -ServerInstance $serverInstance -Database $databaseName -Query $generatorSQLFileWSubstitutions -Verbose) 4> $outputFile

}

Es ist mehr als 3 Jahre her, seit ich dies gefragt habe und ich arbeite derzeit nicht mit SQL-Datenbanken (Big Data, Mongodb usw.). Aber ich werde das sicherlich bald testen. Sie hatten eine großartige Zeit, diese Antwort auszuarbeiten und zur Community beizutragen. Vielen Dank!
Gui

3
Ich benutze StackOverflow schon lange, habe aber erst jetzt angefangen, Beiträge zu leisten. Man kann also sagen, dass ich auch anfange, die SO-Etikette zu lernen. Als ich nach einer solchen Lösung suchte, bin ich auf diesen Thread gestoßen und habe gerade meine erweiterte Lösung hinzugefügt, damit zukünftige Benutzer davon profitieren können. Vielen Dank für Ihren Kommentar.
Jana Sattainathan

Vielen Dank. Ist es möglich, all dies in einem tsql-Skript zu tun - anstatt Powershell zu verwenden?
Niico

5

Wenn Sie Zugriff auf SQL Server 2016 haben, können Sie die Option FOR JSON (mit INCLUDE_NULL_VALUES) verwenden, um die JSON-Ausgabe von einer select-Anweisung abzurufen. Kopieren Sie die Ausgabe und fügen Sie in Visual Studio special -> JSON als Klasse ein.

Eine Art Budgetlösung, kann aber Zeit sparen.


3

Erstellen Sie ein Verfahren zum Erstellen von benutzerdefiniertem Code mithilfe einer Vorlage

create PROCEDURE [dbo].[createCode]
(   
   @TableName sysname = '',
   @befor varchar(max)='public class  @TableName  
{',
   @templet varchar(max)=' 
     public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  ',
   @after varchar(max)='
}'

)
AS
BEGIN 


declare @result varchar(max)

set @befor =replace(@befor,'@TableName',@TableName)

set @result=@befor

select @result = @result 
+ replace(replace(replace(replace(replace(@templet,'@ColumnType',ColumnType) ,'@ColumnName',ColumnName) ,'@ColumnDesc',ColumnDesc),'@ISPK',ISPK),'@max_length',max_length)

from  
(
    select 
    column_id,
    replace(col.name, ' ', '_') ColumnName,
    typ.name as sqltype,
    typ.max_length,
    is_identity,
    pkk.ISPK, 
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'String'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'String'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'String'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        END + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END ColumnType,
      isnull(colDesc.colDesc,'') AS ColumnDesc 
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
            left join
            (
                SELECT c.name  AS 'ColumnName', CASE WHEN dd.pk IS NULL THEN 'false' ELSE 'true' END ISPK           
                FROM        sys.columns c
                    JOIN    sys.tables  t   ON c.object_id = t.object_id    
                    LEFT JOIN (SELECT   K.COLUMN_NAME , C.CONSTRAINT_TYPE as pk  
                        FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
                            LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                        ON K.TABLE_NAME = C.TABLE_NAME
                            AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME
                            AND K.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG
                            AND K.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA            
                        WHERE K.TABLE_NAME = @TableName) as dd
                     ON dd.COLUMN_NAME = c.name
                 WHERE       t.name = @TableName       
            ) pkk  on ColumnName=col.name

    OUTER APPLY (
    SELECT TOP 1 CAST(value AS NVARCHAR(max)) AS colDesc
    FROM
       sys.extended_properties
    WHERE
       major_id = col.object_id
       AND
       minor_id = COLUMNPROPERTY(major_id, col.name, 'ColumnId')
    ) colDesc      
    where object_id = object_id(@TableName)

    ) t

    set @result=@result+@after

    select @result
    --print @result

END

Erstellen Sie jetzt benutzerdefinierten Code

Zum Beispiel c # Klasse

exec [createCode] @TableName='book',@templet =' 
     public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  '

Ausgabe ist

public class  book  
{ 
     public long ID   { get; set; }  //    
     public String Title   { get; set; }  // Book Title  
}

für LINQ

exec [createCode] @TableName='book'
, @befor  ='[System.Data.Linq.Mapping.Table(Name = "@TableName")]
public class @TableName
{',

   @templet  =' 
     [System.Data.Linq.Mapping.Column(Name = "@ColumnName", IsPrimaryKey = @ISPK)]
     public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  
     ' ,

   @after  ='
}'

Ausgabe ist

[System.Data.Linq.Mapping.Table(Name = "book")]
public class book
{ 
     [System.Data.Linq.Mapping.Column(Name = "ID", IsPrimaryKey = true)]
     public long ID   { get; set; }  //   

     [System.Data.Linq.Mapping.Column(Name = "Title", IsPrimaryKey = false)]
     public String Title   { get; set; }  // Book Title  

}

für Java-Klasse

exec [createCode] @TableName='book',@templet =' 
     public @ColumnType @ColumnName ; // @ColumnDesc  
     public @ColumnType get@ColumnName()
     {
        return this.@ColumnName;
     }
     public void set@ColumnName(@ColumnType @ColumnName)
     {
        this.@ColumnName=@ColumnName;
     }

     '

Ausgabe ist

public class  book  
{ 
     public long ID ; //   
     public long getID()
     {
        return this.ID;
     }
     public void setID(long ID)
     {
        this.ID=ID;
     }


     public String Title ; // Book Title  
     public String getTitle()
     {
        return this.Title;
     }
     public void setTitle(String Title)
     {
        this.Title=Title;
     } 
}

für Android SugarOrm Modell

exec [createCode] @TableName='book'
, @befor  ='@Table(name = "@TableName")
public class @TableName
{',
   @templet  =' 
     @Column(name = "@ColumnName")
     public @ColumnType @ColumnName ;// @ColumnDesc  
     ' ,
   @after  ='
}'

Ausgabe ist

@Table(name = "book")
public class book
{ 
     @Column(name = "ID")
     public long ID ;//   

     @Column(name = "Title")
     public String Title ;// Book Title  

}

2

Verwenden Sie diese Option, um NULLABLE-Eigenschaften MIT KOMMENTAR (Zusammenfassung) auszudrucken.
Es ist eine geringfügige Änderung der ersten Antwort

declare @TableName sysname = 'TableName'
declare @result varchar(max) = 'public class ' + @TableName + '
{'
select @result = @result 
+ CASE WHEN ColumnDesc IS NOT NULL THEN '
    /// <summary>
    /// ' + ColumnDesc + '
    /// </summary>' ELSE '' END
+ '
    public ' + ColumnType + ' ' + ColumnName + ' { get; set; }'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'String'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'String'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'String'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        END + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END ColumnType,
        colDesc.colDesc AS ColumnDesc
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    OUTER APPLY (
    SELECT TOP 1 CAST(value AS NVARCHAR(max)) AS colDesc
    FROM
       sys.extended_properties
    WHERE
       major_id = col.object_id
       AND
       minor_id = COLUMNPROPERTY(major_id, col.name, 'ColumnId')
    ) colDesc            
    where object_id = object_id(@TableName)
) t
order by column_id

set @result = @result  + '
}'

print @result

2

Das Visual Studio Magazine hat Folgendes veröffentlicht:

Generieren von .NET POCO-Klassen für SQL-Abfrageergebnisse

Es hat ein herunterladbares Projekt, das Sie erstellen können, geben Sie ihm Ihre SQL-Informationen und es wird die Klasse für Sie herausholen.

Wenn dieses Tool gerade die SQL-Befehle für SELECT, INSERT und UPDATE erstellt hat ....



1

Ich bin verwirrt darüber, was Sie davon wollen, aber hier sind die allgemeinen Optionen beim Entwerfen dessen, was Sie entwerfen möchten.

  1. Verwenden des integrierten ORM in Ihrer Version Visual Studio.
  2. Schreiben Sie selbst eine, ähnlich wie in Ihrem Codebeispiel. Wie immer ist ein Tutorial Ihr bester Freund, wenn Sie sich nicht sicher sind, wie.
  3. Verwenden Sie ein alternatives ORM wie NHibernate .

1

In Anerkennung von Alex 'Lösung und Guilherme für die Bitte habe ich dies für MySQL gemacht, um C # -Klassen zu generieren

set @schema := 'schema_name';
set @table := 'table_name';
SET group_concat_max_len = 2048;
SELECT 
    concat('public class ', @table, '\n{\n', GROUP_CONCAT(a.property_ SEPARATOR '\n'), '\n}') class_
FROM 
    (select
        CONCAT(
        '\tpublic ',
        case 
            when DATA_TYPE = 'bigint' then 'long'
            when DATA_TYPE = 'BINARY' then 'byte[]'
            when DATA_TYPE = 'bit' then 'bool'
            when DATA_TYPE = 'char' then 'string'
            when DATA_TYPE = 'date' then 'DateTime'
            when DATA_TYPE = 'datetime' then 'DateTime'
            when DATA_TYPE = 'datetime2' then 'DateTime'
            when DATA_TYPE = 'datetimeoffset' then 'DateTimeOffset'
            when DATA_TYPE = 'decimal' then 'decimal'
            when DATA_TYPE = 'double' then 'double'
            when DATA_TYPE = 'float' then 'float'
            when DATA_TYPE = 'image' then 'byte[]'
            when DATA_TYPE = 'int' then 'int'
            when DATA_TYPE = 'money' then 'decimal'
            when DATA_TYPE = 'nchar' then 'char'
            when DATA_TYPE = 'ntext' then 'string'
            when DATA_TYPE = 'numeric' then 'decimal'
            when DATA_TYPE = 'nvarchar' then 'string'
            when DATA_TYPE = 'real' then 'double'
            when DATA_TYPE = 'smalldatetime' then 'DateTime'
            when DATA_TYPE = 'smallint' then 'short'
            when DATA_TYPE = 'smallmoney' then 'decimal'
            when DATA_TYPE = 'text' then 'string'
            when DATA_TYPE = 'time' then 'TimeSpan'
            when DATA_TYPE = 'timestamp' then 'DateTime'
            when DATA_TYPE = 'tinyint' then 'byte'
            when DATA_TYPE = 'uniqueidentifier' then 'Guid'
            when DATA_TYPE = 'varbinary' then 'byte[]'
            when DATA_TYPE = 'varchar' then 'string'
            else '_UNKNOWN_'
        end, ' ', 
        COLUMN_NAME, ' {get; set;}') as property_
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = @table AND table_schema = @schema) a
;
Thanks Alex and Guilherme!

Vielen Dank! Ich habe nur danach gesucht!
Roger Far

1

Holen Sie sich QueryFirst , eine Visual Studio-Erweiterung, die Wrapper-Klassen aus SQL-Abfragen generiert. Sie bekommen nicht nur ...

public class MyClass{
    public string MyProp{get;set;}
    public int MyNumberProp{get;set;}
    ...
}

Und als Bonus wird es einwerfen ...

public class MyQuery{
    public static IEnumerable<MyClass>Execute(){}
    public static MyClass GetOne(){}
    ...
}

Sind Sie sicher, dass Sie Ihre Klassen direkt auf Ihren Tischen aufbauen möchten? Tabellen sind ein statischer, normalisierter Datenspeicherungsbegriff, der in die Datenbank gehört. Klassen sind dynamisch, flüssig, verfügbar, kontextspezifisch, möglicherweise denormalisiert. Schreiben Sie echte Abfragen für die Daten, die Sie für eine Operation benötigen, und lassen Sie QueryFirst die Klassen daraus generieren.


1

Dieser Beitrag hat mich mehrmals gerettet. Ich möchte nur meine zwei Cent hinzufügen. Für diejenigen, die keine ORMs verwenden möchten und stattdessen ihre eigenen DAL-Klassen schreiben, wenn Sie 20 Spalten in einer Tabelle und 40 verschiedene Tabellen mit ihren jeweiligen CRUD-Operationen haben, ist dies schmerzhaft und Zeitverschwendung. Ich habe den obigen Code wiederholt, um CRUD-Methoden basierend auf der Tabellenentität und den Eigenschaften zu generieren.

 declare @TableName sysname = 'Tablename'
declare @Result varchar(max) = 'public class ' + @TableName + '
{'

select @Result = @Result + '
    public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

set @Result = @Result  + '
}'

print @Result

declare @InitDataAccess varchar(max) = 'public class '+ @TableName +'DataAccess 
{ '

declare @ListStatement varchar(max) ='public List<'+@TableName+'> Get'+@TableName+'List()
{
 String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
 var itemList = new List<'+@TableName+'>();
          try
            {
                using (var sqlCon = new SqlConnection(conn))
                {
                    sqlCon.Open();
                    var cmd = new SqlCommand
                    {
                        Connection = sqlCon,
                        CommandType = CommandType.StoredProcedure,
                        CommandText = "StoredProcedureSelectAll"
                    };
                    SqlDataReader reader = cmd.ExecuteReader();
                    while (reader.Read())
                    {
                      var item = new '+@TableName+'();
' 
select @ListStatement = @ListStatement + '
item.'+ ColumnName + '= ('+ ColumnType + NullableSign  +')reader["'+ColumnName+'"];
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

select @ListStatement = @ListStatement +'
                        itemList.Add(item);
                    }

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return itemList;
        }'

declare @GetIndividual varchar(max) =  
'public '+@TableName+' Get'+@TableName+'()
{
 String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
 var item = new '+@TableName+'();
          try
            {
                using (var sqlCon = new SqlConnection(conn))
                {
                    sqlCon.Open();
                    var cmd = new SqlCommand
                    {
                        Connection = sqlCon,
                        CommandType = CommandType.StoredProcedure,
                        CommandText = "StoredProcedureSelectIndividual"
                    };
                     cmd.Parameters.AddWithValue("@ItemCriteria", item.id);
                    SqlDataReader reader = cmd.ExecuteReader();
                    if (reader.Read())
                    {' 
select @GetIndividual = @GetIndividual + '
item.'+ ColumnName + '= ('+ ColumnType + NullableSign  +')reader["'+ColumnName+'"];
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

select @GetIndividual = @GetIndividual +'

                    }

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return item;
        }'



declare @InsertStatement varchar(max) = 'public void  Insert'+@TableName+'('+@TableName+' item)
{
 String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;

          try
            {
                using (var sqlCon = new SqlConnection(conn))
                {
                    sqlCon.Open();
                    var cmd = new SqlCommand
                    {
                        Connection = sqlCon,
                        CommandType = CommandType.StoredProcedure,
                        CommandText = "StoredProcedureInsert"
                    };

                    ' 
select @InsertStatement = @InsertStatement + '
 cmd.Parameters.AddWithValue("@'+ColumnName+'", item.'+ColumnName+');
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

select @InsertStatement = @InsertStatement +'

                    cmd.ExecuteNonQuery();

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }'

declare @UpdateStatement varchar(max) = 'public void  Update'+@TableName+'('+@TableName+' item)
{
 String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;

          try
            {
                using (var sqlCon = new SqlConnection(conn))
                {
                    sqlCon.Open();
                    var cmd = new SqlCommand
                    {
                        Connection = sqlCon,
                        CommandType = CommandType.StoredProcedure,
                        CommandText = "StoredProcedureUpdate"
                    };
                    cmd.Parameters.AddWithValue("@UpdateCriteria", item.Id);
                    ' 
select @UpdateStatement = @UpdateStatement + '
 cmd.Parameters.AddWithValue("@'+ColumnName+'", item.'+ColumnName+');
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

select @UpdateStatement = @UpdateStatement +'

                    cmd.ExecuteNonQuery();

                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }'

declare @EndDataAccess varchar(max)  = '
}'
 print @InitDataAccess
 print @GetIndividual
print @InsertStatement
print @UpdateStatement
print @ListStatement
print @EndDataAccess

Natürlich ist es kein kugelsicherer Code und kann verbessert werden. Ich wollte nur zu dieser hervorragenden Lösung beitragen


1

leicht modifiziert von oben Antwort:

declare @TableName sysname = 'HistoricCommand'

declare @Result varchar(max) = '[System.Data.Linq.Mapping.Table(Name = "' + @TableName + '")]
public class Dbo' + @TableName + '
{'

select @Result = @Result + '
    [System.Data.Linq.Mapping.Column(Name = "' + t.ColumnName + '", IsPrimaryKey = ' + pkk.ISPK + ')]
    public ' + ColumnType + NullableSign + ' ' + t.ColumnName + ' { get; set; }
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'string'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id         
    where object_id = object_id(@TableName) 
) t, 
(
                SELECT c.name  AS 'ColumnName', CASE WHEN dd.pk IS NULL THEN 'false' ELSE 'true' END ISPK           
                FROM        sys.columns c
                    JOIN    sys.tables  t   ON c.object_id = t.object_id    
                    LEFT JOIN (SELECT   K.COLUMN_NAME , C.CONSTRAINT_TYPE as pk  
                        FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
                            LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                        ON K.TABLE_NAME = C.TABLE_NAME
                            AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME
                            AND K.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG
                            AND K.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA            
                        WHERE K.TABLE_NAME = @TableName) as dd
                     ON dd.COLUMN_NAME = c.name
                 WHERE       t.name = @TableName            
            ) pkk
where pkk.ColumnName = t.ColumnName
order by ColumnId

set @Result = @Result  + '
}'

print @Result

Dadurch wird die Ausgabe für die vollständige LINQ in der C # -Deklaration benötigt

[System.Data.Linq.Mapping.Table(Name = "HistoricCommand")]
public class DboHistoricCommand
{
    [System.Data.Linq.Mapping.Column(Name = "HistoricCommandId", IsPrimaryKey = true)]
    public int HistoricCommandId { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "PHCloudSoftwareInstanceId", IsPrimaryKey = true)]
    public int PHCloudSoftwareInstanceId { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "CommandType", IsPrimaryKey = false)]
    public int CommandType { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "InitiatedDateTime", IsPrimaryKey = false)]
    public DateTime InitiatedDateTime { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "CompletedDateTime", IsPrimaryKey = false)]
    public DateTime CompletedDateTime { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "WasSuccessful", IsPrimaryKey = false)]
    public bool WasSuccessful { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "Message", IsPrimaryKey = false)]
    public string Message { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "ResponseData", IsPrimaryKey = false)]
    public string ResponseData { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "Message_orig", IsPrimaryKey = false)]
    public string Message_orig { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "Message_XX", IsPrimaryKey = false)]
    public string Message_XX { get; set; }

}


0

Ich richte meine Klassen gerne mit privaten lokalen Mitgliedern und öffentlichen Accessoren / Mutatoren ein. Also habe ich Alex 'Skript oben geändert, um dies auch für alle zu tun, die interessiert sind.

declare @TableName sysname = 'TABLE_NAME'
declare @result varchar(max) = 'public class ' + @TableName + '
{'

SET @result = @result + 
'
    public ' + @TableName + '()
    {}
';

select @result = @result + '
    private ' + ColumnType + ' ' + ' m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ';'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by column_id

SET @result = @result + '
'

select @result = @result + '
    public ' + ColumnType + ' ' + ColumnName + ' { get { return m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ';} set {m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ' = value;} }' from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'float'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'char'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by column_id

set @result = @result  + '
}'

print @result

0

Eine kleine Ergänzung zu den vorherigen Lösungen: Funktioniert object_id(@TableName)nur, wenn Sie sich im Standardschema befinden.

(Select id from sysobjects where name = @TableName)

funktioniert in jedem Schema, sofern @tableName eindeutig ist.


0

Für den Fall, dass es für andere nützlich ist, an einem Code-First-Ansatz mit Attributzuordnungen zu arbeiten, wollte ich etwas, bei dem ich nur eine Entität im Objektmodell binden musste. Dank der Antwort von Carnotaurus habe ich sie gemäß ihrem eigenen Vorschlag erweitert und einige Änderungen vorgenommen.

Dies beruht daher auf dieser Lösung, die ZWEI Teile umfasst, die beide SQL-skalarwertige Funktionen sind:

  1. Eine 'Initial Caps'-Funktion (entnommen aus: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/8a58dbe1-7a4b-4287-afdc-bfecb4e69b23/similar-to-initcap-in-sql- server-tsql und leicht modifiziert, um meine Bedürfnisse zu erfüllen)
ALTER function [dbo].[ProperCase] (@cStringToProper varchar(8000))
returns varchar(8000)
as
begin
   declare  @Position int
    select @cStringToProper = stuff(lower(@cStringToProper) , 1 , 1 , upper(left(@cStringToProper , 1)))
        , @Position = patindex('%[^a-zA-Z][a-z]%' , @cStringToProper collate Latin1_General_Bin)

   while @Position > 0
         select @cStringToProper = stuff(@cStringToProper , @Position , 2 , upper(substring(@cStringToProper , @Position , 2)))
              , @Position = patindex('%[^a-zA-Z][a-z]%' , @cStringToProper collate Latin1_General_Bin)

  select @cStringToProper = replace(@cStringToProper, '_','')

   return @cStringToProper
end
  1. Die Ausgabefunktion selbst, die die Lösung von Carnotaurus erweitert um:

    • Korrekte Ausgabe von Zeilenumbruchzeichen
    • Grundlegende Tabellierung durchführen
    • Schreiben einer geeigneten [Tabelle] Zuordnung (wie vorgeschlagen)
    • Schreiben einer geeigneten [Spalten] Zuordnung, einschließlich des Typnamens (wie vorgeschlagen)
    • Zulassen, dass sich der Entitätsname vom Namen der Tabelle unterscheidet
    • Behebt die Einschränkung des Abschneidens von Print @ Result, wenn Sie Tabellen mit einer großen Anzahl von Spalten haben
CREATE FUNCTION [dbo].[GetEntityObject] (@NameSpace NVARCHAR(MAX), @TableName NVARCHAR(MAX), @EntityName NVARCHAR(MAX))  RETURNS NVARCHAR(MAX) AS BEGIN

DECLARE @result NVARCHAR(MAX)

SET @result = @result + 'using System;' + CHAR(13) + CHAR(13) 

IF (@NameSpace IS NOT NULL)  BEGIN
    SET @result = @result + 'namespace ' + @NameSpace  + CHAR(13) + '{' + CHAR(13)  END

SET @result = @result + '[Table(name: ' + CHAR(34) + @TableName + CHAR(34) + ')]' + CHAR(13) SET @result = @result + 'public class ' + @EntityName + CHAR(13) + '{' + CHAR(13) 

SET @result = @result + '#region Instance Properties' + CHAR(13)  

SELECT @result = @result + CHAR(13)     + '[Column(name: ' + CHAR(34) + OriginalColumnName + CHAR(34) + ', TypeName = ' + CHAR(34) + DataType
+ CHAR(34) + ')]' + CHAR(13)
    + 'public ' + ColumnType + ' ' + ColumnName + ' { get; set; } ' + CHAR(13)  FROM (
    SELECT dbo.ProperCase (c.COLUMN_NAME)   AS ColumnName 
        , CASE c.DATA_TYPE   
            WHEN 'bigint' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int64?' ELSE 'Int64' END
            WHEN 'binary' THEN 'Byte[]'
            WHEN 'bit' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Boolean?' ELSE 'Boolean' END            
            WHEN 'char' THEN 'String'
            WHEN 'date' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetime' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetime2' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                        
            WHEN 'datetimeoffset' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTimeOffset?' ELSE 'DateTimeOffset' END                                    
            WHEN 'decimal' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                    
            WHEN 'float' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Single?' ELSE 'Single' END                                    
            WHEN 'image' THEN 'Byte[]'
            WHEN 'int' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int32?' ELSE 'Int32' END
            WHEN 'money' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                
            WHEN 'nchar' THEN 'String'
            WHEN 'ntext' THEN 'String'
            WHEN 'numeric' THEN
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                            
            WHEN 'nvarchar' THEN 'String'
            WHEN 'real' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Double?' ELSE 'Double' END                                                                        
            WHEN 'smalldatetime' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
            WHEN 'smallint' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Int16?' ELSE 'Int16'END            
            WHEN 'smallmoney' THEN  
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Decimal?' ELSE 'Decimal' END                                                                        
            WHEN 'text' THEN 'String'
            WHEN 'time' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'TimeSpan?' ELSE 'TimeSpan' END                                         
            WHEN 'timestamp' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
            WHEN 'tinyint' THEN 
                CASE C.IS_NULLABLE
                    WHEN 'YES' THEN 'Byte?' ELSE 'Byte' END                                                
            WHEN 'uniqueidentifier' THEN 'Guid'
            WHEN 'varbinary' THEN 'Byte[]'
            WHEN 'varchar' THEN 'String'
            ELSE 'Object'
        END AS ColumnType
        , c.ORDINAL_POSITION        , c.COLUMN_NAME as OriginalColumnName       ,c.DATA_TYPE as DataType

FROM    INFORMATION_SCHEMA.COLUMNS c WHERE   c.TABLE_NAME = @TableName) t ORDER BY t.ORDINAL_POSITION

SET @result = @result + CHAR(13) + '#endregion Instance Properties' + CHAR(13)  

SET @result = @result  + '}' + CHAR(13)

IF (@TableName IS NOT NULL)  BEGIN
    SET @result = @result + CHAR(13) + '}'  END

return @result END

Verwendung in MS SQL Management Studio:

SELECT dbo.GetEntityObject ('MyNameSpace', 'MyTableName', 'MyEntityName')

führt zu einem Spaltenwert, den Sie kopieren und in Visual Studio einfügen können.

Wenn es jemandem hilft, dann großartig!


Ich habe aufgehört, [Schlüssel] -Attribute hinzuzufügen, weil es einfach genug ist, diese manuell hinzuzufügen. Möglicherweise wird auch ein Fehler angezeigt, wenn Sie Real nicht Edm.Double zuordnen. [Nullable = True, DefaultValue =]. Wenn dies der Fall ist, ändern Sie entweder die relevante Eigenschaft oder die Funktion zum Zuordnen von Real zu Single.
VorTechS

0

Ich habe hier Ideen aus mehreren SQL-basierten Antworten, hauptsächlich der Stammantwort von Alex Aza, in klassify zusammengefasst , einer Konsolenanwendung, die alle Klassen für eine bestimmte Datenbank gleichzeitig generiert:


Beispiel: Eine Tabelle Userssieht folgendermaßen aus:

+----+------------------+-----------+---------------------+
| Id |       Name       | Username  |        Email        |
+----+------------------+-----------+---------------------+
|  1 | Leanne Graham    | Bret      | Sincere@april.biz   |
|  2 | Ervin Howell     | Antonette | Shanna@melissa.tv   |
|  3 | Clementine Bauch | Samantha  | Nathan@yesenia.net  |
+----+------------------+-----------+---------------------+

klassifygeneriert eine Datei mit dem Namen Users.cs:

    public class User 
    {
        public int Id {get; set; }
        public string Name { get;set; }
        public string Username { get; set; }
        public string Email { get; set; }
    }

Für jede Tabelle wird eine Datei ausgegeben. Verwerfen Sie, was Sie nicht verwenden.

Verwendung

 --out, -o:
        output directory     << defaults to the current directory >>
 --user, -u:
        sql server user id   << required >>
 --password, -p:
        sql server password  << required >>
 --server, -s:
        sql server           << defaults to localhost >>
 --database, -d:
        sql database         << required >>
 --timeout, -t:
        connection timeout   << defaults to 30 >>
 --help, -h:
        show help

0

Ich dachte nur, ich würde meine eigene Variation der Top-Antwort für jeden hinzufügen, der interessiert ist. Die Hauptmerkmale sind:

  • Es werden automatisch Klassen für alle Tabellen im gesamten Schema generiert. Geben Sie einfach den Schemanamen an.
  • Es werden der Klasse und jeder Eigenschaft System.Data.Linq.Mapping-Attribute hinzugefügt. Nützlich für alle, die Linq to SQL verwenden.

    declare @TableName sysname
    declare @Result varchar(max)
    declare @schema varchar(20) = 'dbo'
    DECLARE @Cursor CURSOR
    
    SET @Cursor = CURSOR FAST_FORWARD FOR
    SELECT DISTINCT tablename = rc1.TABLE_NAME
    FROM INFORMATION_SCHEMA.Tables rc1
    where rc1.TABLE_SCHEMA = @schema
    
    OPEN @Cursor FETCH NEXT FROM @Cursor INTO @TableName
    
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
    set @Result = '[Table(Name = "' + @schema + '.' + @TableName + '")]
    public class ' + Replace(@TableName, '$', '_') + '
    {'
    
    select @Result = @Result + '
        [Column' + PriKey +']
        public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
    '
    from
    (
        select 
            replace(col.name, ' ', '_') ColumnName,
            col.column_id ColumnId,
            case typ.name 
                when 'bigint' then 'long'
                when 'binary' then 'byte[]'
                when 'bit' then 'bool'
                when 'char' then 'string'
                when 'date' then 'DateTime'
                when 'datetime' then 'DateTime'
                when 'datetime2' then 'DateTime'
                when 'datetimeoffset' then 'DateTimeOffset'
                when 'decimal' then 'decimal'
                when 'float' then 'double'
                when 'image' then 'byte[]'
                when 'int' then 'int'
                when 'money' then 'decimal'
                when 'nchar' then 'string'
                when 'ntext' then 'string'
                when 'numeric' then 'decimal'
                when 'nvarchar' then 'string'
                when 'real' then 'float'
                when 'smalldatetime' then 'DateTime'
                when 'smallint' then 'short'
                when 'smallmoney' then 'decimal'
                when 'text' then 'string'
                when 'time' then 'TimeSpan'
                when 'timestamp' then 'long'
                when 'tinyint' then 'byte'
                when 'uniqueidentifier' then 'Guid'
                when 'varbinary' then 'byte[]'
                when 'varchar' then 'string'
                else 'UNKNOWN_' + typ.name
            end ColumnType,
            case 
                when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
                then '?' 
                else '' 
            end NullableSign,
            case
                when pk.CONSTRAINT_NAME is not null and ic.column_id is not null then '(IsPrimaryKey = true, IsDbGenerated = true)'
                when pk.CONSTRAINT_NAME is not null then '(IsPrimaryKey = true)'
                when ic.column_id is not null then '(IsDbGenerated = true)'
                else ''
            end PriKey
        from sys.columns col
        join sys.types typ on col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
        left outer join sys.identity_columns ic on ic.column_id = col.column_id and col.object_id = ic.object_id
        left outer join (
            SELECT  K.TABLE_NAME ,
                K.COLUMN_NAME ,
                K.CONSTRAINT_NAME
            FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                    JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON C.TABLE_NAME = K.TABLE_NAME
                                                                     AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
                                                                     AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
                                                                     AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME
            where C.CONSTRAINT_TYPE = 'PRIMARY KEY'
        ) pk on pk.COLUMN_NAME = col.name and pk.TABLE_NAME = @TableName
        where col.object_id = object_id(@schema + '.' + @TableName)
    ) t
    order by ColumnId
    
    set @Result = @Result  + '
    }
    
    '
    
    print @Result
    
    FETCH NEXT FROM @Cursor INTO @TableName
    end
    
    CLOSE @Cursor DEALLOCATE @Cursor
    GO

-1

Sie haben es gerade getan, solange Ihre Tabelle zwei Spalten enthält und so etwas wie "tblPeople" heißt.

Sie können jederzeit Ihre eigenen SQL-Wrapper schreiben. Eigentlich mache ich es lieber so, ich HASSE generierten Code auf jede Art und Weise.

Erstellen Sie möglicherweise eine DALKlasse und lassen Sie eine Methode aufrufen GetPerson(int id), die die Datenbank nach dieser Person abfragt und dann Ihr PersonObjekt aus der Ergebnismenge erstellt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.