Register Register Member Login Member Login Member Login Forgot Password ??
PHP , ASP , ASP.NET, VB.NET, C#, Java , jQuery , Android , iOS , Windows Phone
 

Registered : 109,027

HOME > .NET Framework > Forum > SET COLLATE ชอง SQL SERVER ผ่าน ENTITY FRAMEWORK แบบเอาให้มั่น คั้นให้อยู่มือกันเลยน่ะครับ



 

SET COLLATE ชอง SQL SERVER ผ่าน ENTITY FRAMEWORK แบบเอาให้มั่น คั้นให้อยู่มือกันเลยน่ะครับ

 



Topic : 135138



โพสกระทู้ ( 0 )
บทความ ( 0 )



สถานะออฟไลน์




หัวข้อ :
ต้องการ set collate ของ sql server(ฐานข้อมูลอื่นก็ใช้ได้ครับไปเพิ่ม .net connector ของฐานข้อมูลนั้นมาก็พอ) database ให้สนับสนุนภาษาไทย เพราะในบางกรณีเราไม่ได้เป็นคนติดตั้งตัว SQL SERVER เองหรือไปยุ่งกับค่า DEFAULT ของเครื่องที่ติดตั้งไม่ได้ ทำให้ไม่แน่ใจว่าจะได้ฐานข้อมูลที่ suport ภาษาไทยตามต้องการไหม
ที่มาที่ไป :
คือใช้ link https://www.thaicreate.com/dotnet/forum/062440.html ใช้ในงานของตัวเอง เลยเอาสิ่งที่ได้ไปกลับมาคืนน่ะครับ
framework :
Entity framework 6.2.x , ADO.NET พร้อม.net connector ของฐานข้อมูลนั้นตามข้างต้น
วิธีการ/ลำดับการทำงาน :
ใช้ t-sql ในการสั่งให้ database เปลี่ยน collate ตามที่ต้องการ (ในกรณีนี้คือ Thai_CI_AS) จะใช้ ALTER DATABASE เป็นหลัก แต่เนื่องจากคำสั่ง ALTER นี้เป็นกลุ่ม DDL Command ทำให้มีปัญหาหลายอย่างจนสั่งผ่าน RAW SQL EXECUTE ของ Entity framework (ขอใช้ EF ละกันครับยาวเกิ้น) จึงต้องทำผ่าน ADO.NET แบบดั้งเดิมแทน อีกทั้งเป็นคำสั่งที่ทำให้เกิด effect อย่างมากจึงแนะนำให้ใช้ขณะที่ไม่เกิดผลกระทบมากมาย ส่วนตัวผมเองนั้นเนื่องจากเป็นสาย code first เลยเอาไปติดตั้งขณะที่ฐานข้อมูลกำลังถูกสร้างครั้งแรก (ตัวงานจะไม่มีฐานข้อมูลเลย จะสร้างครั้งเดียวตอน run ครั้งแรกแบบอัตโนแมว และอาจมีการอัพเดทบ้างนิดๆหน่อยๆ) แต่ก็เอาไปประยกต์ใช้เรียกที่ตำแหน่ง/ลำดับไหนก็ได้ตามที่เห็นสมควรครับ และที่ต้องเรียกผ่าน ADO.NET แบบ Asyncronous ก็เพราะชุดคำสั่งนี้ต้องทำไล่เรียงกันไป อีกทั้งต้องให้แน่ใจว่าทำเสร็จครบทุกคำสั่งจริงๆ ไม่งั้นมันมีเพี้ยน เช่น รันผ่านไปแล้ว แต่ฐานข้อมูลถูก lock ไว้ใน mode single user กันเลยทีเดียว

รายละเอียด :
code นี้เป็นแกนหลักของทั้งหมด ตามร่ายมานั่นแหละครับ เอาไปแปะตรงไหนก็ได้ตามสมควร แต่ระวังๆกันหน่อยละกันครับ ผิดที่ผิดเวลานี่ความปวดกะบาลตามมาแน่นวล

ปล.ทำไมต้องเป็น static method เพราะมันจะมี overload แบบ extension mehod เพื่อความสะดวกในการเรียกใช้ต่่างกรรมต่างวาระน่ะครับ และตัวมันเองจะเรียกใช้ method อื่นอีก จะลงไล่ลำดับถัดจาก overload ของมันไปนะครับ อ้อ overload นี่ถ้าไม่ใช้ก็ไม่ต้องสนใจมันนะครับ จะเฉดหัวขับไล่ไสส่งก็ตามที่สะดวก
Code (C#)
         public static void SQLServerSetDatabaseCollation
           (string ConnectionString, string DatabaseName, string SpecificCollation = "Thai_CI_AS")
        {
            //ref https://www.thaicreate.com/dotnet/forum/062440.html                        
            string tempStr = string.Empty;
            StringBuilder sb = new StringBuilder();

            // WITH SQL-DDL COMMAND NOT ALLOW PASS VALUE FROM PARAMETER            
            // ENTITY.EXECUTESQLCOMMAND NOT SUPPORT ALTER COMMAND THEIR YIELD ERROR WITH CONNECTION RESET
            // THEN EXECUTE PASSTHROUGH TRADDITION (ASYNC)ADO.NET
            sb.Append("IF DB_ID('"+ DatabaseName + "') IS NOT NULL");
            sb.Append("BEGIN");
            sb.Append("   ALTER DATABASE " + DatabaseName + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE;");
            sb.Append("   ALTER DATABASE " + DatabaseName + " COLLATE " + SpecificCollation + ";");
            sb.Append("   ALTER DATABASE " + DatabaseName + " SET MULTI_USER;");
            sb.Append("END ;");

            tempStr = sb.ToString();

            // USE ASYNC CALL PREVENTS ALL RESULT HAVE COMPLETED ONE BY ONE.
            SqlServerAsyncExecuteCommandWithADODotNet(ConnectionString, tempStr)
                .ContinueWith(t => Console.WriteLine(t.Exception)
                    , TaskContinuationOptions.OnlyOnFaulted);

        }


Overload :
Code (C#)
        public static void SQLServerSetDatabaseCollation
            (this SqlConnectionStringBuilder SpecificConnectionBuilder, string SpecificCollation = "Thai_CI_AS")
        {
            SQLServerSetDatabaseCollation(SpecificConnectionBuilder.ConnectionString
                , SpecificConnectionBuilder.InitialCatalog, SpecificCollation);
        }

        public static void SQLServerSetDatabaseCollation<TContext>
         (this TContext Context, string SpecificCollation = "Thai_CI_AS")
            where TContext : DbContext
        {
            SQLServerSetDatabaseCollation(Context.Database.Connection.ConnectionString
                , Context.Database.Connection.Database, SpecificCollation);
        }


inner call method :
Code (C#)
        public static async Task<int> SqlServerAsyncExecuteCommandWithADODotNet(string ConnectionString
            , string CommandText, params object[] Parameters)
        {
            int iret = 0;
            string tempStr = CommandText;
            string ParamName = string.Empty;
            try
            {
                using (var conn = new SqlConnection(ConnectionString))
                {
                    using (var cmd = conn.CreateCommand())
                    {
                        for (int i = 0; i < Parameters.Length; i++)
                        {
                            ParamName = "@param" + (i + 1).ToString();
                            tempStr = tempStr.Replace("{" + i.ToString() + "}", ParamName);
                            cmd.Parameters.AddWithValue(ParamName, Parameters[i]);
                        }
                        cmd.CommandText = tempStr;
                        await conn.OpenAsync();
                        await cmd.ExecuteNonQueryAsync();
                        iret = 1;
                    }
                }
            }
            catch (SqlException e)//(Exception e)
            {
                //Debug.WriteLine("At SqlServerAsyncExecuteCommandWithADODotNet : [" + e.Message + "]");
                iret = -1;
            }
            return iret;
        }



usage:
การใช้งานก็เรียกใช้แบบบ้านๆเดิมๆนั่นแหละครับ
Code (C#)
        public CreateDatabaseIfNotExistsWithCollationEx(TContext context, string Collation = "Thai_CI_AS")
        {
            if (!context.Database.Exists())
            {
                context.Database.CreateIfNotExists();
                context.SQLServerSetDatabaseCollation<TContext>(Collation);
            }

        }


อ่อปิดท้ายด้วยอีก method ที่เอาใช้ตรวจสอบ collate ของ database และส่วนยิบย่อยเพิ่มเติมเดี๋ยวจะต่อใน comment อีกทีข้างล่่างนะครับ เดี๋ยวมันจะยาวไป
Code (C#)
        public static string SQLServerGetDatebaseCollation<TContext>(this TContext SpecificDBContext)
            where TContext : DbContext
        {
            StringBuilder sb = new StringBuilder();
            string DatabaseName = SpecificDBContext.Database.Connection.Database;            

            sb.AppendLine("SELECT collation_name");
            sb.AppendLine("FROM sys.databases");
            sb.AppendLine("WHERE [name] = @databaseName;");

            var DatabaseNameParam = new SqlParameter("@databaseName", DatabaseName);

            //for debug only
            String str = sb.ToString();

            str = SpecificDBContext.Database.SqlQuery<string>
                (str, DatabaseNameParam).FirstOrDefault<string>();

            return str;
        }




Tag : .NET, Ms SQL Server 2016, C#, Windows









ประวัติการแก้ไข
2020-04-22 02:04:54
2020-04-22 02:05:21
2020-04-22 02:31:46
2020-04-22 02:40:26
Move To Hilight (Stock) 
Send To Friend.Bookmark.
Date : 2020-04-22 02:01:54 By : baka baka View : 1403 Reply : 9
 

 

No. 1



โพสกระทู้ ( 0 )
บทความ ( 0 )



สถานะออฟไลน์


ดูๆ code แล้วมันก็ไม่ค่อยเกียวกับ EF สักเท่าไหร่ แต่ในการใช้งานดังที่กราบหว่างอกหว่างใจไปกันแล้วนั้น ผมใชังาน ณ ตำแหน่งการติดตั้งครั้งแรก ซึ่งตามแบบแผนของ EF เขาจะให้ยุ่งกับการทำงานส่วนนี้ผ่านทาง database initializer ซึ่งมีด้วยกัน 4 แบบ ตามนี้ >> https://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspx เหตุผลก็ดังว่า ไม่อยากรบกวนใจระบบ ตรงนี้ทำกันครั้งเดียวให้มันจบๆไป เพื่อการนี้ผมเลือกใช้ custom initializer แบบว่าไหนๆก็ไหนๆแล้วน่ะครับ ตัว code จะวางลงไป 2 ส่วนคือ
1. ส่วน custom class ที่สืบแล้วทอดมาจาก interface ที่ชื่อว่า IDatabaseInitializer (แม่แบบของ database initializer ทั้งมวล) ก็ยัดส่วนสร้าง database แล้วก็ ALETER Collate มันเสีย ที่ constructor ของเขาไป
Code (C#)
    public class CreateDatabaseIfNotExistsWithCollationEx<TContext>
        : IDatabaseInitializer<TContext> where TContext : DbContext
    {
        public void InitializeDatabase(TContext context) { }

        public CreateDatabaseIfNotExistsWithCollationEx(TContext context, string Collation = "Thai_CI_AS")
        {
            if (!context.Database.Exists())
            {
                context.Database.CreateIfNotExists();
                context.SQLServerSetDatabaseCollation<TContext>(Collation);
            }

        }
    }




2. ใน DbContext ส่วน constructor ของเราเพื่อติดตั้ง database initializer ให้ลงล้อกตามแบบแผนของตัว EF ไป ที่เหลือก็ปล่อยให้มันไหลไปตาม flow ครับ
Code (C#)
 public class SchoolContext : DbContext
    {
        public SchoolContext() : base()
        {
            SetContextInitializer();
        }
        public SchoolContext(string ConnectionString) : base(ConnectionString)
        {
            SetContextInitializer();
        }

        void SetContextInitializer()
        {
            Debug.WriteLine("SetContextInitializer");

            Database.SetInitializer<SchoolContext>
                (new CreateDatabaseIfNotExistsWithCollationEx<SchoolContext>(this,"Thai_CI_AS"));
            //Database.SetInitializer<SchoolContext>(new DropCreateDatabaseAlwaysWithThaiCollation<SchoolContext>());

        }      

        public DbSet<Student> Students { get; set; }
        public DbSet<Grade> Grades { get; set; }

    }


ปล. อันที่จริงเรื่อง Collate นี่มันจะง่ายกรุบๆกริบๆ เพียงแค่เราไป set ผ่าน SQL Management ที่เขาแจกๆกันนั่นก็ได้ แต่จากประสบการณ์นี้บางที่บางเจ้าบางคนท่านไม่ยอมให้เราไปยุ่งครับ ก็เลยเตรียมๆแบบ worst case เอาไว้ก่อน เดี๋ยวงานจะสดุดเพราะเรื่องเล็กๆ ก็เท่านั้นเองครับ








ประวัติการแก้ไข
2020-04-22 02:22:37
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-22 02:19:24 By : baka baka
 


 

No. 2



โพสกระทู้ ( 9,542 )
บทความ ( 2 )



สถานะออฟไลน์


เปลี่ยน วิธีใช้เป็นของตระกูล n???? ไม่ว่าจะ collate เป็นภาษาใด ก็ไม่เกี่ยวกับของเราแล้วครับ

เช่น nchar nvarchar ntext แถมรองรับ ทุก web server
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-22 07:13:50 By : Chaidhanan
 

 

No. 3

Guest


@baka baka คุณกำลังจะบอกอะไรครับ

คุณใช้คำว่า ประสบการณ์ แต่ถ้าผมบอกอายุของคุณให้รับทราบรับรู้ คุณก็จะงงงง เหมือนผมงงงง เหมือนกัน

Source Code ของคุณ สำหรับผม มันก็ไม่แตกต่างกับคุณยก Dbase/FoxPro/Clipper/Clarion/etc..
มาอธิบายให้ผมฟัง คุณไม่เข้าใจก็ไม่เป็นไร

ปล. คุณอธิบายได้ดีครับ แต่วิธีของคุณ ผมมองว่า เด็กอนุบาล
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-23 19:31:23 By : หน้าฮี
 


 

No. 4

Guest


ถ้าคุณยังสงสัยในตัวของคนชื่อหน้าฮี จะบอกให้ก็ได้ มีสักกี่คนที่เขียน SQL Qeury ปิดงบทางบัญชีได้
ที่เห็นฯ ก็ธรรมดาฯ

ผมคิดแบบนี้นะ

ปล. เก่ง C#/VB/etc.. มากแค่ไหน มันก็ยังไม่พอหรอก ถ้าความน่าเชื่อถือของคุณมันต่ำพอฯ กับตัวของคนชื่อหน้าฮี
ไม่ได้ว่าคุณนะ แต่อยากแนะนำและเล่าประสบการณ์จริงแท้ ให้ฟังก็เท่านั้นเอง

(ไม่เคยคิดจะยกมือไหว้ใครเลย ในเมืองไทยนี้)
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-23 19:48:43 By : หน้าฮี
 


 

No. 5

Guest


โอ้ ดราม่าได้ด้วยหรอเนี่ย ก็ถ้าไปกระทบอะไรใครก็ขออภัยอย่างแรงๆ ไม่ได้ตั้งใจครับ
( คือถ้าตั้งใจจะตรงไปตรงมาไม่ต้องอ้อมอะไรกันน่ะครับ )

สาเหตุที่เอามาลงก็เพราะผมยกเอาส่วนนึงที่ใช้การอ้างอิงจากที่นี่ไป แล้วเอาไปใช้แบบนั้นอย่างนั้นแหละ
นี่คือจุดประสงค์ ผมก็ว่าผมเขียนตรงๆ ไปอย่างชัดเจนอยู่นะ ถ้าอ่านแล้วตีความเป็นอย่างอื่นก็เอาที่สะดวกครับ
จริงๆว่าจะเอามาลงตั้งนานแต่ก็ลืมแล้วลืมอีก เพราะใช้งานมาพอสมควร ซึ่งปัจจุบันเปลี่ยนเป็น EF CORE
ไปรื้อเอา code บางส่วนมาใช้ใหม่กับ .net core เลยเจอ แล้วก็เอามาลงเอาตอนนี้
ส่วนจะน่าเชื่อถือหรือเอาไปทำประโยชน์ได้ไหมก็แล้วแต่จะเห็นสมควร ผมไม่ได้เรียกร้องนี่นา

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

ปล.สมัครแล้วก็ลืม password ต้องขออภัยอย่างสูงครับ
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-24 00:50:57 By : ลืม password เองล่ะ
 


 

No. 6



โพสกระทู้ ( 9,542 )
บทความ ( 2 )



สถานะออฟไลน์


ตอบความคิดเห็นที่ : 5 เขียนโดย : ลืม password เองล่ะ เมื่อวันที่ 2020-04-24 00:50:57
รายละเอียดของการตอบ ::
สำหรับผมไม่ได้ดราม่านะ ผมแค่แนะนำให้ใช้ unicode แทนครับ เขาจะเซทระบบยังไงไม่ต้องสนใจ
เราก็ยังใช้ภาษาของเราได้อยู่ ขอเพียงให้เราสามารถสร้างตาราง สร้าง procedure ได้เอง ก็ไม่ต้องแคร์ adminแล้ว


มายังไงก็ออกไปหยั่งงั้น ไม่ต้อง convert ดีที่สุด
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-24 05:15:19 By : Chaidhanan
 


 

No. 7

Guest


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


ขอบคุณสำหรับ ประสบการณ์ที่นำมาแบ่งปันครับ
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-24 06:44:52 By : PhrayaDev
 


 

No. 8



โพสกระทู้ ( 9,542 )
บทความ ( 2 )



สถานะออฟไลน์


ตอบความคิดเห็นที่ : 7 เขียนโดย : PhrayaDev เมื่อวันที่ 2020-04-24 06:44:52
รายละเอียดของการตอบ ::
สาธุ สาธุ

แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-24 08:54:28 By : Chaidhanan
 


 

No. 9



โพสกระทู้ ( 1,458 )
บทความ ( 0 )



สถานะออฟไลน์
Twitter Facebook Blogger

ตอบความคิดเห็นที่ : 8 เขียนโดย : Chaidhanan เมื่อวันที่ 2020-04-24 08:54:28
รายละเอียดของการตอบ ::
จำพระคุณเจ้ามาอีกที ผมเองยังทำไม่ได้ เลยส่งต่อ 555

แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2020-04-24 10:30:04 By : PhrayaDev
 

   

ค้นหาข้อมูล


   
 

แสดงความคิดเห็น
Re : SET COLLATE ชอง SQL SERVER ผ่าน ENTITY FRAMEWORK แบบเอาให้มั่น คั้นให้อยู่มือกันเลยน่ะครับ
 
 
รายละเอียด
 
ตัวหนา ตัวเอียง ตัวขีดเส้นใต้ ตัวมีขีดกลาง| ตัวเรืองแสง ตัวมีเงา ตัวอักษรวิ่ง| จัดย่อหน้าอิสระ จัดย่อหน้าชิดซ้าย จัดย่อหน้ากึ่งกลาง จัดย่อหน้าชิดขวา| เส้นขวาง| ขนาดตัวอักษร แบบตัวอักษร
ใส่แฟลช ใส่รูป ใส่ไฮเปอร์ลิ้งค์ ใส่อีเมล์ ใส่ลิ้งค์ FTP| ใส่แถวของตาราง ใส่คอลัมน์ตาราง| ตัวยก ตัวห้อย ตัวพิมพ์ดีด| ใส่โค้ด ใส่การอ้างถึงคำพูด| ใส่ลีสต์
smiley for :lol: smiley for :ken: smiley for :D smiley for :) smiley for ;) smiley for :eek: smiley for :geek: smiley for :roll: smiley for :erm: smiley for :cool: smiley for :blank: smiley for :idea: smiley for :ehh: smiley for :aargh: smiley for :evil:
Insert PHP Code
Insert ASP Code
Insert VB.NET Code Insert C#.NET Code Insert JavaScript Code Insert C#.NET Code
Insert Java Code
Insert Android Code
Insert Objective-C Code
Insert XML Code
Insert SQL Code
Insert Code
เพื่อความเรียบร้อยของข้อความ ควรจัดรูปแบบให้พอดีกับขนาดของหน้าจอ เพื่อง่ายต่อการอ่านและสบายตา และตรวจสอบภาษาไทยให้ถูกต้อง

อัพโหลดแทรกรูปภาพ

Notice

เพื่อความปลอดภัยของเว็บบอร์ด ไม่อนุญาติให้แทรก แท็ก [img]....[/img] โดยการอัพโหลดไฟล์รูปจากที่อื่น เช่นเว็บไซต์ ฟรีอัพโหลดต่าง ๆ
อัพโหลดแทรกรูปภาพ ให้ใช้บริการอัพโหลดไฟล์ของไทยครีเอท และตัดรูปภาพให้พอดีกับสกรีน เพื่อความโหลดเร็วและไฟล์ไม่ถูกลบทิ้ง

   
  เพื่อความปลอดภัยและการตรวจสอบ กระทู้ที่แทรกไฟล์อัพโหลดไฟล์จากที่อื่น อาจจะถูกลบทิ้ง
 
โดย
อีเมล์
บวกค่าให้ถูก
<= ตัวเลขฮินดูอารบิก เช่น 123 (หรือล็อกอินเข้าระบบสมาชิกเพื่อไม่ต้องกรอก)







Exchange: นำเข้าสินค้าจากจีน, Taobao, เฟอร์นิเจอร์, ของพรีเมี่ยม, ร่ม, ปากกา, power bank, แฟลชไดร์ฟ, กระบอกน้ำ

Load balance : Server 02
ThaiCreate.Com Logo
© www.ThaiCreate.Com. 2003-2024 All Rights Reserved.
ไทยครีเอทบริการ จัดทำดูแลแก้ไข Web Application ทุกรูปแบบ (PHP, .Net Application, VB.Net, C#)
[Conditions Privacy Statement] ติดต่อโฆษณา 081-987-6107 อัตราราคา คลิกที่นี่