สร้างคลาสจากตารางฐานข้อมูล


214

ฉันจะสร้างคลาสจากวัตถุตาราง SQL Server ได้อย่างไร

ฉันไม่ได้พูดถึงการใช้ ORM ฉันแค่ต้องสร้างเอนทิตี้ (คลาสง่าย) สิ่งที่ต้องการ:

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

รับตารางบางอย่างเช่น:

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



14
ทำไมไม่ให้ Entity Framework สร้างคลาสให้คุณ แต่อย่าใช้คลาสที่เกี่ยวข้องกับการเข้าถึงฐานข้อมูล?
John Saunders

ฉันไม่เห็นด้วยกับ @John Saunders มากขึ้น ฉันเคยทำเองมาก่อน แต่มันใช้เวลานานเกินไป EF ทำถูกต้องเป็นครั้งแรกในกรณีส่วนใหญ่ ถ้าไม่การปรับแต่งคลาสที่สร้างนั้นใช้เวลาน้อยกว่าการลงมือทำเองทั้งหมด ฉันมีสิ่งที่ดีกว่าที่จะทำกับเวลาของฉันมากกว่าเขียนโค้ดที่ตัวสร้าง ORM สามารถทำเพื่อฉันได้ ฉันเข้าใจว่าไม่ชอบรหัสที่สร้างขึ้น แต่การประหยัดเวลา (และค่าใช้จ่าย) เป็นเรื่องที่คุ้มค่าอย่างน้อยสำหรับฉัน
David

4
ฉันคิดว่า EF จะเป็นทางออกที่ดีที่สุด ความเป็นไปได้อีกอย่างหนึ่งก็คือ LINQ ไปยัง SQL Classes คุณเพียงแค่เพิ่มลงในโครงการของคุณและให้การเชื่อมต่อฐานข้อมูล ถัดไปคุณเพียงแค่เลือกตารางที่คุณต้องการและมันจะทำให้บางคลาสสำหรับคุณ
Kevin Cloet

2
ในทางปฏิบัติ EF ไม่ได้เป็นทางออกที่ดีที่สุดในทุกกรณี ตัวอย่างหนึ่งอาจมีผู้พัฒนาที่ไม่มีประสบการณ์หลายคนที่เปลี่ยนแปลง crass ไปยังไฟล์ edmx ซึ่งทำให้เกิดความขัดแย้งของรุ่นที่จะพูดน้อยที่สุด ... นอกจากนี้ตัวเลือกอาจไม่สามารถใช้ได้เช่นกัน ตัวอย่างเช่นลูกค้าเป้าหมายทางเทคนิคอาจไม่ต้องการให้คุณใช้ด้วยเหตุผลใด ๆ ก็ตาม
CarneyCode

คำตอบ:


683

ตั้งค่า @TableName เป็นชื่อของตารางของคุณ

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
สำหรับNullable Typesให้ผนวกรหัสนี้ระหว่างendและColumnTypeในสคริปต์ SQL ของ Alex + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END
stun

6
@AlexAza คุณควรเปลี่ยน "เมื่อ ' float' then 'float'" เป็น " when 'float' then 'double'และคุณควรเปลี่ยน" when 'real' then 'double'"เป็น" when 'real' then 'float'"ดูเหมือนว่าคุณมีประเภทเหล่านั้นสับสน C # เทียบเท่ากับการลอย SQL เป็นคู่และ C # เทียบเท่ากับ SQL จริงเป็นลอย .
หาด Jared

4
คำตอบที่ดี แต่คุณต้องเปลี่ยนprint @Resultเป็นprint CAST(@Result AS TEXT)อย่างอื่นมันจะถูกตัดทอนลงบนโต๊ะขนาดใหญ่
Robert McKee

2
วิธีการเกี่ยวกับการเพิ่มคำอธิบายประกอบข้อมูลสำหรับการตรวจสอบนี้ - เช่นความยาวฟิลด์สูงสุด? :)
niico

3
ผมเคยได้มาเป็นรุ่นที่จะส่งออกทุกตารางของฐานข้อมูลเป็น POCOs
Uwe Keim

72

ฉันไม่สามารถรับคำตอบของ Alex ในการทำงานกับ Sql Server 2008 R2 ดังนั้นฉันเขียนมันใหม่โดยใช้หลักการพื้นฐานเดียวกัน ตอนนี้อนุญาตสำหรับสกีมาและมีการแก้ไขหลายอย่างสำหรับการแม็พคุณสมบัติคอลัมน์ (รวมถึงการแม็พประเภทวันที่ที่สามารถเป็นโมฆะได้กับประเภทค่า C # ที่ไม่สามารถใช้ได้) นี่คือ 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

มันสร้าง C # ดังต่อไปนี้:

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
    }

}

มันอาจเป็นความคิดที่จะใช้ EF, Linq ถึง Sql หรือแม้แต่นั่งร้าน อย่างไรก็ตามมีบางครั้งที่การเขียนโค้ดเช่นนี้มีประโยชน์ ตรงไปตรงมาฉันไม่ชอบการใช้คุณสมบัติการนำทางของ EF ที่โค้ดที่สร้างทำให้การเรียกฐานข้อมูลแยกต่างหาก 19,200 เพื่อเติมตาราง 1000 แถว สิ่งนี้สามารถทำได้ในการเรียกฐานข้อมูลเดียว อย่างไรก็ตามอาจเป็นเพราะสถาปนิกด้านเทคนิคของคุณไม่ต้องการให้คุณใช้ EF และสิ่งที่คล้ายกัน ดังนั้นคุณต้องกลับไปใช้รหัสเช่นนี้ ... โดยบังเอิญมันอาจเป็นความคิดที่จะตกแต่งคุณสมบัติแต่ละอย่างด้วยคุณสมบัติสำหรับ DataAnnotations ฯลฯ แต่ฉันเก็บ POCO นี้ไว้อย่างเคร่งครัด

แก้ไขแล้ว สำหรับTimeStampและGuid?


+1 นี่ใช้ได้ดีสำหรับฉันด้วย ฉันใช้ EF สำหรับฐานข้อมูลหลักของเรา แต่ต้องการคว้า sproc จากฐานข้อมูลอื่นและไม่ต้องการเขียนรหัสโครงการ EF ทั้งหมดสำหรับเรื่องนั้นดังนั้นฉันจะสร้างชั้นเรียนเพื่อรองรับผล sproc ของฉันอย่างรวดเร็ว ... ขอบคุณ
jim tollan

ฉันยังคงใช้มัน แต่ตอนนี้เราได้รวมคุณสมบัติคุณลักษณะ MVC สำหรับความยาวสตริง ฯลฯ
CarneyCode

สร้างคลาสที่ว่างสำหรับฉันโดยไม่มีคุณสมบัติ / คอลัมน์
highwingers

@ highwingers: คุณใช้สคีมาและชื่อตารางที่ถูกต้องหรือไม่ กรุณาแสดงให้ฉันเห็นการดำเนินการของคุณด้านบน
CarneyCode

นี่คือหนึ่งขัด ฉันใช้สิ่งนี้ แต่ต้องขอบคุณอเล็กซ์ที่สร้างต้นฉบับขึ้นมา
Tejasvi Hegde

20

รุ่น VB

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'

แต่ไม่มี Get / SET?
highwingers

1
@ highwingers ตั้งแต่ Visual Studio 2010 ไม่จำเป็นต้องมีstackoverflow.com/a/460032/618186
guanome

ฉันต้องเพิ่มข้อความ "ใช้ MyDatabase" ที่ด้านบนเพื่อทำงาน มิฉะนั้นจะสร้างคุณสมบัติคลาสที่ไม่รู้จักสองคู่
Cesar

ดีมาก. แต่floatควรจะไปDouble, byte[]ไปByte()
RichieRich

ทำได้ดีมาก ฉันลองใช้มุมมองและใช้งานได้เหมือนมีเสน่ห์!
Hanlet Escaño

14

ช้าไปหน่อย แต่ฉันได้สร้างเครื่องมือเว็บเพื่อช่วยสร้างวัตถุ C # (หรืออื่น ๆ ) จากผลลัพธ์ SQL, SQL Table และ SQL SP

sql2object.com

สิ่งนี้จะปลอดภัยจริงๆคุณต้องพิมพ์คุณสมบัติและประเภททั้งหมด

หากประเภทไม่เป็นที่รู้จักค่าเริ่มต้นจะถูกเลือก


1
ไม่เลว แต่ไม่สามารถใช้สคริปต์นิยามตารางเป็นแหล่งที่มา
anatol

มันยอดเยี่ยมมาก :) มันยอดเยี่ยมมากสำหรับทั้งผลลัพธ์และตาราง จะดีจริงๆถ้าคุณสามารถปรับเปลี่ยนเพื่อละเว้นสิ่งทั้งหมดCREATE TABLEดังนั้นฉันสามารถตัดและวางทุกอย่าง นอกจากนี้หากคุณมีโอกาสคุณสามารถเพิ่ม 'Trim ()' ในนั้น - มันล้มเหลวหากมีบรรทัดว่างที่จุดเริ่มต้นจากนั้นผู้คนจะยอมแพ้ ง่ายถ้าคุณรู้ว่าจะลบมัน - แต่คุณจะสูญเสียคนเมื่อคุณให้ข้อผิดพลาด
Simon_Weaver

รูปแบบสำหรับชุดผลลัพธ์ SQL คืออะไร ฉันเพิ่งคัดลอกและวางจากหน้าต่างแสดงผลข้อความและให้เขตข้อมูลเดียวที่มีชื่อคอลัมน์ทั้งหมด: - / เคล็ดลับอะไร
Simon_Weaver

หรือคุณสามารถทำให้มันเป็นโอเพ่นซอร์สและให้ชุมชนสร้างมันขึ้นมาในแบบที่พวกเขาต้องการ
Adil H. Raza

มันไม่ได้สร้างคลาส C # จากสคริปต์ "สร้างตาราง"
เมห์เม็ต

12

ฉันพยายามให้ 2 เซ็นต์ของฉัน

0) QueryFirst https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst Query-first เป็นส่วนขยายสตูดิโอภาพสำหรับการทำงานอย่างชาญฉลาดกับ SQL ในโครงการ C # ใช้เทมเพลต. sql ที่ให้มาเพื่อพัฒนาคิวรีของคุณ เมื่อคุณบันทึกไฟล์ Query จะเรียกใช้คิวรีของคุณก่อนดึงสคีมาและสร้างสองคลาสและอินเทอร์เฟซ: คลาส wrapper ที่มีเมธอด Execute (), ExecuteScalar (), ExecuteNonQuery () ฯลฯ อินเทอร์เฟซที่สอดคล้องกันและ POCO encapsulating บรรทัดของผลลัพธ์ป้อนคำอธิบายรูปภาพที่นี่

1) Sql2Objects สร้างคลาสที่เริ่มต้นจากผลลัพธ์ของแบบสอบถาม (แต่ไม่ใช่ DAL) ป้อนคำอธิบายรูปภาพที่นี่

2) https://docs.microsoft.com/en-us/ef/ef6/resources/tools ป้อนคำอธิบายรูปภาพที่นี่

3) https://visualstudiomagazine.com/articles/2012/12/11/sqlqueryresults-code-generation.aspx ป้อนคำอธิบายรูปภาพที่นี่

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


9

ใช่เหล่านี้ดีถ้าคุณใช้ ORM ง่าย ๆ เช่น Dapper

หากคุณใช้. Net คุณสามารถสร้างไฟล์ XSD ณ รันไทม์พร้อมชุดข้อมูลใด ๆ โดยใช้เมธอด WriteXmlSchema http://msdn.microsoft.com/en-us/library/xt7k72x8(v=vs.110).aspx

แบบนี้:

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

จากตรงนั้นคุณสามารถใช้ xsd.exe เพื่อสร้างคลาสที่ XML เป็นอนุกรมได้จากพรอมต์คำสั่งสำหรับนักพัฒนา http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

แบบนี้:

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

8

หากต้องการพิมพ์คุณสมบัติ NULLABLE ให้ใช้สิ่งนี้
มันเพิ่มการดัดแปลงเล็กน้อยสำหรับสคริปต์ของ Alex Aza สำหรับCASEบล็อกคำสั่ง

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

ฉันพยายามใช้คำแนะนำด้านบนและในกระบวนการปรับปรุงตามแนวทางแก้ไขในหัวข้อนี้

ให้เราบอกว่าคุณใช้คลาสพื้นฐาน (ObservableObject ในกรณีนี้) ที่ใช้งาน PropertyChanged Event คุณจะทำสิ่งนี้ ฉันอาจจะเขียนบล็อกโพสต์หนึ่งวันในบล็อกของฉัน sqljana.wordpress.com

โปรดแทนที่ค่าสำหรับตัวแปรสามตัวแรก:

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

ชั้นฐานจะขึ้นอยู่กับบทความของ Josh Smith ที่นี่จากhttp://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

ฉันเปลี่ยนชื่อคลาสเป็น ObservableObject และใช้ประโยชน์จากคุณสมบัติ ac # 5 โดยใช้แอตทริบิวต์ CallerMemberName

//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
    }
}

นี่คือส่วนที่พวกคุณจะชอบมากกว่านี้ ฉันสร้างสคริปต์ Powershell เพื่อสร้างสำหรับตารางทั้งหมดในฐานข้อมูล SQL มันขึ้นอยู่กับปราชญ์ Powershell ชื่อ Invad-SQLCmd2 cmdlet ซึ่งสามารถดาวน์โหลดได้จากที่นี่: http://gallery.technet.microsoft.com/ScriptCenter/7985b7ef-ed89-4dfd-b02a-433cc4e30894/

เมื่อคุณมี cmdlet แล้วสคริปต์ Powershell ที่จะสร้างสำหรับตารางทั้งหมดจะกลายเป็นเรื่องง่าย (ทำการแทนที่ตัวแปรด้วยค่าเฉพาะของคุณ)

. 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

}

เป็นเวลานานกว่า 3 ปีแล้วที่ฉันถามสิ่งนี้และฉันไม่ได้ทำงานกับฐานข้อมูล sql ในขณะนี้ (ข้อมูลขนาดใหญ่, mongodb, ฯลฯ ) แต่ฉันจะทำการทดสอบในไม่ช้าคุณมีช่วงเวลาที่ดีในการอธิบายคำตอบนี้และให้ความช่วยเหลือชุมชน ขอบคุณมาก!
Gui

3
ฉันใช้ StackOverflow มานาน แต่ตอนนี้เริ่มมีส่วนร่วมเท่านั้น ดังนั้นคุณสามารถพูดได้ว่าฉันเริ่มเรียนรู้มารยาท SO ด้วย เมื่อฉันกำลังมองหาวิธีแก้ปัญหาเช่นนี้ฉันก็สะดุดกับหัวข้อนี้และเพิ่งเพิ่มโซลูชันเพิ่มเติมของฉันเพื่อให้ผู้ใช้ในอนาคตได้รับประโยชน์จากมัน ขอบคุณสำหรับความคิดเห็นของคุณ
Jana Sattainathan

ขอบคุณ เป็นไปได้ที่จะทำทั้งหมดนี้ในสคริปต์ tsql - แทนที่จะใช้ PowerShell?
niico

5

หากคุณสามารถเข้าถึง SQL Server 2016 คุณสามารถใช้ตัวเลือก FOR JSON (พร้อม INCLUDE_NULL_VALUES) เพื่อรับเอาต์พุต JSON จากคำสั่ง select คัดลอกผลลัพธ์จากนั้นใน Visual Studio วางแบบพิเศษ -> วาง JSON เป็นคลาส

ชนิดของโซลูชันงบประมาณ แต่อาจประหยัดเวลา


3

สร้าง PROCEDURE สำหรับสร้างรหัสที่กำหนดเองโดยใช้เทมเพลต

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

ตอนนี้สร้างรหัสที่กำหนดเอง

เช่น c # class

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

ผลลัพธ์คือ

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

สำหรับ 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  ='
}'

ผลลัพธ์คือ

[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  

}

สำหรับคลาส java

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

     '

ผลลัพธ์คือ

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

สำหรับ android sugarOrm model

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

ผลลัพธ์คือ

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

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

}

2

หากต้องการพิมพ์คุณสมบัติ NULLABLE ที่มีความคิดเห็น (สรุป) ให้ใช้สิ่งนี้
เป็นการแก้ไขคำตอบแรกเล็กน้อย

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

Visual Studio Magazine ตีพิมพ์สิ่งนี้:

การสร้าง. NET POCO Classes สำหรับผลลัพธ์ SQL Query

มีโครงการที่สามารถดาวน์โหลดได้ที่คุณสามารถสร้างให้ข้อมูล SQL ของคุณและมันจะทำให้คลาสของคุณพัง

ตอนนี้หากเครื่องมือนั้นเพิ่งสร้างคำสั่ง SQL สำหรับ SELECT, INSERT และ UPDATE ....



1

ฉันสับสนกับสิ่งที่คุณต้องการจากสิ่งนี้ แต่นี่คือตัวเลือกทั่วไปเมื่อออกแบบสิ่งที่คุณต้องการออกแบบ

  1. ใช้ ORM ในตัวใน Visual Studio เวอร์ชันของคุณ
  2. เขียนหนึ่งเองคล้ายกับตัวอย่างรหัสของคุณ ตามปกติการสอนคือเพื่อนที่ดีที่สุดของคุณหากคุณไม่แน่ใจ
  3. ใช้ออมทางเลือกเช่นNHibernate

1

ขอบคุณที่โซลูชันของ Alex และ Guilherme ขอให้ฉันทำสิ่งนี้สำหรับ MySQL เพื่อสร้างคลาส C #

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!

ขอบคุณ! ฉันแค่มองหาสิ่งนี้!
Roger Far

1

หยิบQueryFirstสตูดิโอส่วนต่อขยายที่สร้าง visual class wrapper จากการสืบค้น SQL คุณไม่เพียง แต่รับ ...

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

และเป็นโบนัสมันจะเข้า ...

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

แน่ใจหรือไม่ว่าคุณต้องการเรียนโดยตรงบนโต๊ะของคุณ? ตารางเป็นแนวคิดในการจัดเก็บข้อมูลแบบสแตติกที่ได้รับการทำให้เป็นมาตรฐานที่อยู่ในฐานข้อมูล ชั้นเรียนเป็นแบบไดนามิกของเหลวที่ใช้แล้วทิ้งบริบทที่เฉพาะเจาะจงอาจจะผิดปกติ ทำไมไม่เขียนเคียวรีจริงสำหรับข้อมูลที่คุณต้องการสำหรับการดำเนินการและให้ QueryFirst สร้างคลาสจากนั้น


1

โพสต์นี้ช่วยฉันได้หลายครั้ง ฉันแค่ต้องการเพิ่มสองเซ็นต์ของฉัน สำหรับผู้ที่ไม่ต้องการใช้ ORM และแทนที่จะเขียนคลาส DAL ของตนเองเมื่อคุณมีคอลัมน์ 20 คอลัมน์ในตารางและ 40 ตารางที่แตกต่างกับการดำเนินงาน CRUD ของพวกเขาเจ็บปวดและเสียเวลา ฉันทำซ้ำรหัสข้างต้นสำหรับการสร้างวิธีการ CRUD ตามเอนทิตีของตารางและคุณสมบัติ

 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

แน่นอนว่ามันไม่ใช่รหัสกระสุนและสามารถปรับปรุงได้ แค่อยากมีส่วนร่วมกับทางออกที่ยอดเยี่ยมนี้


1

แก้ไขเล็กน้อยจากคำตอบยอดนิยม:

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

ซึ่งทำให้ผลลัพธ์ที่จำเป็นสำหรับ LINQ เต็มในการประกาศ C #

[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

ฉันชอบที่จะตั้งค่าคลาสของฉันกับสมาชิกในพื้นที่ส่วนตัวและผู้เข้าถึง / mutators สาธารณะ ดังนั้นฉันจึงแก้ไขสคริปต์ของ Alex ด้านบนเพื่อทำเช่นนั้นสำหรับทุกคนที่ถูกขัดจังหวะ

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

ส่วนเพิ่มเติมเล็ก ๆ ของโซลูชันก่อนหน้า: object_id(@TableName)ใช้ได้เฉพาะเมื่อคุณอยู่ในสคีมาเริ่มต้นเท่านั้น

(Select id from sysobjects where name = @TableName)

ทำงานในสคีมาใด ๆ ที่ให้ @tableName ไม่ซ้ำกัน


0

ในกรณีที่มันมีประโยชน์กับคนอื่น ๆ ที่ทำงานเกี่ยวกับวิธีการรหัสแรกโดยใช้การแมปแอตทริบิวต์ที่ฉันต้องการสิ่งที่เพิ่งทำให้ฉันต้องผูกเอนทิตีในรูปแบบวัตถุ ขอบคุณคำตอบของ Carnotaurus ฉันจึงขยายออกไปตามคำแนะนำของพวกเขาและทำการปรับแต่งสองสามครั้ง

สิ่งนี้ขึ้นอยู่กับโซลูชันนี้ประกอบด้วยสองส่วนซึ่งทั้งสองอย่างเป็นฟังก์ชัน SQL Scalar-Valued

  1. ฟังก์ชัน 'Initial Caps' (นำมาจาก: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/8a58dbe1-7a4b-4287-afdc-bfecb4e69b23/similar-to-initcap-in-sql- เซิร์ฟเวอร์ -qql และปรับเปลี่ยนเล็กน้อยเพื่อตอบสนองความต้องการของฉัน)
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. ฟังก์ชั่นการส่งออกตัวเองซึ่งขยายการแก้ปัญหา Carnotaurus โดย:

    • ส่งเอาต์พุตอักขระขึ้นบรรทัดใหม่อย่างถูกต้อง
    • ดำเนินการตารางพื้นฐานบางอย่าง
    • การเขียนการแมป [ตาราง] ที่เหมาะสม (ตามที่แนะนำ)
    • เขียนการแมป [คอลัมน์] ที่เหมาะสมรวมถึงชื่อประเภท (ตามที่แนะนำ)
    • การอนุญาตให้ชื่อเอนทิตีแตกต่างจากชื่อของตาราง
    • แก้ไขข้อ จำกัด ของการตัดทอนการพิมพ์ @Result เมื่อคุณมีตารางที่มีคอลัมน์จำนวนมาก
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

การใช้งานจากภายใน MS SQL Management Studio:

เลือก dbo.GetEntityObject ('MyNameSpace', 'MyTableName', 'MyEntityName')

จะส่งผลให้ค่าคอลัมน์คุณสามารถคัดลอกและวางลงใน Visual Studio

ถ้ามันช่วยได้ทุกคนก็ยอดเยี่ยม!


ฉันหยุดการเพิ่มคุณสมบัติ [คีย์] สั้น ๆ เพราะมันง่ายพอที่จะเพิ่มด้วยตนเอง นอกจากนี้คุณอาจได้รับข้อผิดพลาดตามเส้นทางที่ล้มเหลวในการจับคู่ Real กับ Edm.Double [Nullable = True, DefaultValue =] หากเป็นกรณีนี้ให้ลองปรับเปลี่ยนคุณสมบัติที่เกี่ยวข้องหรือฟังก์ชั่นเพื่อแมป Real เป็น Single
VorTechS

0

ฉันรวบรวมความคิดจากคำตอบหลายคำสั่ง SQL ที่นี่ส่วนใหญ่คำตอบหลักโดย Alex Aza เป็นklassifyซึ่งเป็นแอปพลิเคชันคอนโซลที่สร้างคลาสทั้งหมดสำหรับฐานข้อมูลที่ระบุในครั้งเดียว:


ตัวอย่างเช่นกำหนดตารางUsersที่มีลักษณะดังนี้:

+----+------------------+-----------+---------------------+
| 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  |
+----+------------------+-----------+---------------------+

klassifyจะสร้างไฟล์ชื่อ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; }
    }

มันจะส่งออกหนึ่งไฟล์สำหรับทุกตาราง ทิ้งสิ่งที่คุณไม่ได้ใช้

การใช้

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

แค่คิดว่าฉันจะเพิ่มคำตอบยอดนิยมของฉันสำหรับผู้ที่สนใจ คุณสมบัติหลักคือ:

  • มันจะสร้างคลาสโดยอัตโนมัติสำหรับตารางทั้งหมดในสคีมาทั้งหมด เพียงระบุชื่อสคีมา
  • มันจะเพิ่ม System.Data.Linq.Mapping คุณลักษณะให้กับคลาสและแต่ละคุณสมบัติ มีประโยชน์สำหรับทุกคนที่ใช้ Linq กับ SQL

    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

คุณเพิ่งทำตราบใดที่ตารางของคุณมีสองคอลัมน์และถูกเรียกว่า 'tblPeople'

คุณสามารถเขียนชุดคำสั่ง SQL ของคุณเองได้ตลอดเวลา จริง ๆ แล้วฉันชอบที่จะทำอย่างนั้นฉันเกลียดสร้างรหัสในแบบใด

อาจสร้างDALชั้นเรียนและมีวิธีการที่เรียกGetPerson(int id)ว่าสอบถามฐานข้อมูลสำหรับบุคคลนั้นแล้วสร้างPersonวัตถุของคุณจากชุดผลลัพธ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.