MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

LINQ เจจเฉ‡ .NET เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจธเจผเจ•เจคเฉ€เจธเจผเจพเจฒเฉ€ เจจเจตเฉ€เจ‚ เจกเจพเจŸเจพ เจนเฉ‡เจฐเจพเจซเฉ‡เจฐเฉ€ เจญเจพเจธเจผเจพ เจตเจœเฉ‹เจ‚ เจฆเจพเจ–เจฒ เจ•เฉ€เจคเจพ เจนเฉˆเฅค เจ‡เจธเจฆเฉ‡ เจนเจฟเฉฑเจธเฉ‡ เจตเจœเฉ‹เจ‚ LINQ เจคเฉ‹เจ‚ SQL เจคเฉเจนเจพเจจเฉ‚เฉฐ DBMS เจจเจพเจฒ เจ•เจพเจซเจผเฉ€ เจธเฉเจตเจฟเจงเจพเจœเจจเจ• เจขเฉฐเจ— เจจเจพเจฒ เจธเฉฐเจšเจพเจฐ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจเจ‚เจŸเจฟเจŸเฉ€ เจซเจฐเฉ‡เจฎเจตเจฐเจ•เฅค เจนเจพเจฒเจพเจ‚เจ•เจฟ, เจ…เจ•เจธเจฐ เจ‡เจธเจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ, เจกเจฟเจตเฉˆเจฒเจชเจฐ เจ‡เจน เจฆเฉ‡เจ–เจฃเจพ เจญเฉเฉฑเจฒ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจ•เจฟ เจธเจตเจพเจฒ เจ•เจฐเจจ เจฏเฉ‹เจ— เจชเฉเจฐเจฆเจพเจคเจพ, เจคเฉเจนเจพเจกเฉ‡ เจ•เฉ‡เจธ เจตเจฟเฉฑเจš เจเจ‚เจŸเจฟเจŸเฉ€ เจซเจฐเฉ‡เจฎเจตเจฐเจ•, เจ•เจฟเจธ เจ•เจฟเจธเจฎ เจฆเฉ€ SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจคเจฟเจ†เจฐ เจ•เจฐเฉ‡เจ—เจพเฅค

เจ†เจ‰ เจ‡เฉฑเจ• เจ‰เจฆเจพเจนเจฐเจฃ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจฆเฉ‹ เจฎเฉเฉฑเจ– เจจเฉเจ•เจคเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจตเฉ‡เจ–เฉ€เจเฅค
เจ…เจœเจฟเจนเจพ เจ•เจฐเจจ เจฒเจˆ, SQL เจธเจฐเจตเจฐ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจฌเจฃเจพเจ“, เจ…เจคเฉ‡ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ€ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ‡เจธ เจตเจฟเฉฑเจš เจฆเฉ‹ เจŸเฉ‡เจฌเจฒ เจฌเจฃเจพเจ“:

เจŸเฉ‡เจฌเจฒ เจฌเจฃเจพเจ‰เจฃเจพ

USE [TEST]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Ref](
	[ID] [int] NOT NULL,
	[ID2] [int] NOT NULL,
	[Name] [nvarchar](255) NOT NULL,
	[InsertUTCDate] [datetime] NOT NULL,
 CONSTRAINT [PK_Ref] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Ref] ADD  CONSTRAINT [DF_Ref_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO

USE [TEST]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Customer](
	[ID] [int] NOT NULL,
	[Name] [nvarchar](255) NOT NULL,
	[Ref_ID] [int] NOT NULL,
	[InsertUTCDate] [datetime] NOT NULL,
	[Ref_ID2] [int] NOT NULL,
 CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Customer] ADD  CONSTRAINT [DF_Customer_Ref_ID]  DEFAULT ((0)) FOR [Ref_ID]
GO

ALTER TABLE [dbo].[Customer] ADD  CONSTRAINT [DF_Customer_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO

เจนเฉเจฃ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ€ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจšเจฒเจพ เจ•เฉ‡ เจฐเฉˆเจซ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจคเจฟเจ†เจฐ เจ•เจฐเฉ€เจ:

เจฐเฉˆเจซ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจญเจฐเจจเจพ

USE [TEST]
GO

DECLARE @ind INT=1;

WHILE(@ind<1200000)
BEGIN
	INSERT INTO [dbo].[Ref]
           ([ID]
           ,[ID2]
           ,[Name])
    SELECT
           @ind
           ,@ind
           ,CAST(@ind AS NVARCHAR(255));

	SET @ind=@ind+1;
END 
GO

เจšเจฒเฉ‹ เจ‡เจธเฉ‡ เจคเจฐเฉเจนเจพเจ‚ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ€ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ—เจพเจนเจ• เจธเจพเจฐเจฃเฉ€ เจจเฉ‚เฉฐ เจญเจฐเฉ€เจ:

เจ—เจพเจนเจ• เจธเจพเจฐเจฃเฉ€ เจจเฉ‚เฉฐ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเจพ เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

USE [TEST]
GO

DECLARE @ind INT=1;
DECLARE @ind_ref INT=1;

WHILE(@ind<=12000000)
BEGIN
	IF(@ind%3=0) SET @ind_ref=1;
	ELSE IF (@ind%5=0) SET @ind_ref=2;
	ELSE IF (@ind%7=0) SET @ind_ref=3;
	ELSE IF (@ind%11=0) SET @ind_ref=4;
	ELSE IF (@ind%13=0) SET @ind_ref=5;
	ELSE IF (@ind%17=0) SET @ind_ref=6;
	ELSE IF (@ind%19=0) SET @ind_ref=7;
	ELSE IF (@ind%23=0) SET @ind_ref=8;
	ELSE IF (@ind%29=0) SET @ind_ref=9;
	ELSE IF (@ind%31=0) SET @ind_ref=10;
	ELSE IF (@ind%37=0) SET @ind_ref=11;
	ELSE SET @ind_ref=@ind%1190000;
	
	INSERT INTO [dbo].[Customer]
	           ([ID]
	           ,[Name]
	           ,[Ref_ID]
	           ,[Ref_ID2])
	     SELECT
	           @ind,
	           CAST(@ind AS NVARCHAR(255)),
	           @ind_ref,
	           @ind_ref;


	SET @ind=@ind+1;
END
GO

เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚, เจธเจพเจจเฉ‚เฉฐ เจฆเฉ‹ เจŸเฉ‡เจฌเจฒ เจชเฉเจฐเจพเจชเจค เจนเฉ‹เจ, เจœเจฟเจจเฉเจนเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ‡เฉฑเจ• เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพ เจฆเฉ€เจ†เจ‚ 1 เจฎเจฟเจฒเฉ€เจ…เจจ เจคเฉ‹เจ‚ เจตเฉฑเจง เจ•เจคเจพเจฐเจพเจ‚ เจนเจจ, เจ…เจคเฉ‡ เจฆเฉ‚เจœเฉ€ เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพ เจฆเฉ€เจ†เจ‚ 10 เจฎเจฟเจฒเฉ€เจ…เจจ เจคเฉ‹เจ‚ เจตเฉฑเจง เจ•เจคเจพเจฐเจพเจ‚ เจนเจจเฅค

เจนเฉเจฃ เจตเจฟเจœเจผเฉ‚เจ…เจฒ เจธเจŸเฉ‚เจกเฉ€เจ“ เจตเจฟเฉฑเจš เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจŸเฉˆเจธเจŸ เจตเจฟเจœเจผเฉ‚เจ…เจฒ C# เจ•เฉฐเจธเฉ‹เจฒ เจเจช (.NET เจซเจฐเฉ‡เจฎเจตเจฐเจ•) เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจ…เฉฑเจ—เฉ‡, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจจเจพเจฒ เจ‡เฉฐเจŸเจฐเฉˆเจ•เจŸ เจ•เจฐเจจ เจฒเจˆ เจ‡เจ•เจพเจˆ เจซเจฐเฉ‡เจฎเจตเจฐเจ• เจฒเจˆ เจ‡เฉฑเจ• เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจœเฉ‹เฉœเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค
เจ‡เจธ เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจจ เจฒเจˆ, เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ 'เจคเฉ‡ เจธเฉฑเจœเจพ-เจ•เจฒเจฟเฉฑเจ• เจ•เจฐเฉ‹ เจ…เจคเฉ‡ เจธเฉฐเจฆเจฐเจญ เจฎเฉ€เจจเฉ‚ เจคเฉ‹เจ‚ NuGet เจชเฉˆเจ•เฉ‡เจœ เจชเฉเจฐเจฌเฉฐเจงเจฟเจค เจ•เจฐเฉ‹ เจฆเฉ€ เจšเฉ‹เจฃ เจ•เจฐเฉ‹:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจซเจฟเจฐ, เจฆเจฟเจธเจฃ เจตเจพเจฒเฉ€ NuGet เจชเฉˆเจ•เฉ‡เจœ เจชเฉเจฐเจฌเฉฐเจงเจจ เจตเจฟเฉฐเจกเฉ‹ เจตเจฟเฉฑเจš, เจ–เฉ‹เจœ เจตเจฟเฉฐเจกเฉ‹ เจตเจฟเฉฑเจš "เจเจ‚เจŸเจฟเจŸเฉ€ เจซเจฐเฉ‡เจฎเจตเจฐเจ•" เจธเจผเจฌเจฆ เจฆเจฐเจœ เจ•เจฐเฉ‹ เจ…เจคเฉ‡ เจ‡เจ•เจพเจˆ เจซเจฐเฉ‡เจฎเจตเจฐเจ• เจชเฉˆเจ•เฉ‡เจœ เจจเฉ‚เฉฐ เจšเฉเจฃเฉ‹ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเฉ‹:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจ…เฉฑเจ—เฉ‡, App.config เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš, configSection เจคเฉฑเจค เจจเฉ‚เฉฐ เจฌเฉฐเจฆ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจฌเจฒเจพเจ• เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ:

<connectionStrings>
    <add name="DBConnection" connectionString="data source=ะ˜ะœะฏ_ะญะšะ—ะ•ะœะŸะ›ะฏะ ะ_MSSQL;Initial Catalog=TEST;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>

เจ•เจจเฉˆเจ•เจธเจผเจจเจธเจŸเฉเจฐเจฟเฉฐเจ— เจตเจฟเฉฑเจš เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เจจเฉˆเจ•เจธเจผเจจ เจธเจคเจฐ เจฆเจฐเจœ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

เจนเฉเจฃ เจตเฉฑเจ–-เจตเฉฑเจ– เจซเจพเจˆเจฒเจพเจ‚ เจตเจฟเฉฑเจš 3 เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจฌเจฃเจพเจ‰:

  1. IBaseEntityID เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ
    namespace TestLINQ
    {
        public interface IBaseEntityID
        {
            int ID { get; set; }
        }
    }
    

  2. IBaseEntityName เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ
    namespace TestLINQ
    {
        public interface IBaseEntityName
        {
            string Name { get; set; }
        }
    }
    

  3. IBaseNameInsertUTCDate เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ
    namespace TestLINQ
    {
        public interface IBaseNameInsertUTCDate
        {
            DateTime InsertUTCDate { get; set; }
        }
    }
    

เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ€ เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจ…เจธเฉ€เจ‚ เจ†เจชเจฃเฉ€เจ†เจ‚ เจฆเฉ‹ เจธเฉฐเจธเจฅเจพเจตเจพเจ‚ เจฒเจˆ เจ‡เฉฑเจ• เจฌเฉ‡เจธ เจ•เจฒเจพเจธ BaseEntity เจฌเจฃเจพเจตเจพเจ‚เจ—เฉ‡, เจœเจฟเจธ เจตเจฟเฉฑเจš เจธเจพเจ‚เจเฉ‡ เจ–เฉ‡เจคเจฐ เจธเจผเจพเจฎเจฒ เจนเฉ‹เจฃเจ—เฉ‡:

เจฌเฉ‡เจธ เจ•เจฒเจพเจธ BaseEntity เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ

namespace TestLINQ
{
    public class BaseEntity : IBaseEntityID, IBaseEntityName, IBaseNameInsertUTCDate
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime InsertUTCDate { get; set; }
    }
}

เจ…เฉฑเจ—เฉ‡, เจ…เจธเฉ€เจ‚ เจ†เจชเจฃเฉ€เจ†เจ‚ เจฆเฉ‹ เจธเฉฐเจธเจฅเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจตเฉฑเจ–เจฐเฉ€เจ†เจ‚ เจซเจพเจˆเจฒเจพเจ‚ เจตเจฟเฉฑเจš เจฌเจฃเจพเจตเจพเจ‚เจ—เฉ‡:

  1. เจฐเฉˆเจซ เจ•เจฒเจพเจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace TestLINQ
    {
        [Table("Ref")]
        public class Ref : BaseEntity
        {
            public int ID2 { get; set; }
        }
    }
    

  2. เจ—เจพเจนเจ• เจตเจฐเจ— เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace TestLINQ
    {
        [Table("Customer")]
        public class Customer: BaseEntity
        {
            public int Ref_ID { get; set; }
            public int Ref_ID2 { get; set; }
        }
    }
    

เจนเฉเจฃ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ€ เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• UserContext เจธเฉฐเจฆเจฐเจญ เจฌเจฃเจพเจ‰:

UserContex เจ•เจฒเจพเจธ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ

using System.Data.Entity;

namespace TestLINQ
{
    public class UserContext : DbContext
    {
        public UserContext()
            : base("DbConnection")
        {
            Database.SetInitializer<UserContext>(null);
        }

        public DbSet<Customer> Customer { get; set; }
        public DbSet<Ref> Ref { get; set; }
    }
}

เจธเจพเจจเฉ‚เฉฐ MS SQL เจธเจฐเจตเจฐ เจฒเจˆ EF เจฆเฉเจ†เจฐเจพ LINQ เจคเฉ‹เจ‚ SQL เจฆเฉ‡ เจจเจพเจฒ เจ“เจชเจŸเฉ€เจฎเจพเจˆเจœเฉ‡เจธเจผเจจ เจŸเฉˆเจธเจŸ เจ•เจฐเจตเจพเจ‰เจฃ เจฒเจˆ เจ‡เฉฑเจ• เจคเจฟเจ†เจฐ-เจฌเจฃเจพเจ‡เจ† เจนเฉฑเจฒ เจชเฉเจฐเจพเจชเจค เจนเฉ‹เจ‡เจ† เจนเฉˆ:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจนเฉเจฃ Program.cs เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจฆเจพเจ–เจฒ เจ•เจฐเฉ‹:

Program.cs เจซเจผเจพเจˆเจฒ

using System;
using System.Collections.Generic;
using System.Linq;

namespace TestLINQ
{
    class Program
    {
        static void Main(string[] args)
        {
            using (UserContext db = new UserContext())
            {
                var dblog = new List<string>();
                db.Database.Log = dblog.Add;

                var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                 && (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

                var result = query.Take(1000).ToList();

                Console.WriteLine(dblog[1]);

                Console.ReadKey();
            }
        }
    }
}

เจ…เฉฑเจ—เฉ‡, เจ†เจ“ เจ†เจชเจฃเจพ เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฒเจพเจ‚เจš เจ•เจฐเฉ€เจเฅค

เจ•เฉฐเจฎ เจฆเฉ‡ เจ…เฉฐเจค 'เจคเฉ‡, เจ•เฉฐเจธเฉ‹เจฒ 'เจคเฉ‡ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจชเฉเจฐเจฆเจฐเจธเจผเจฟเจค เจ•เฉ€เจคเฉ‡ เจœเจพเจฃเจ—เฉ‡:

เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

SELECT TOP (1000) 
    [Extent1].[Ref_ID] AS [Ref_ID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [dbo].[Customer] AS [Extent1]
    INNER JOIN [dbo].[Ref] AS [Extent2] ON ([Extent1].[Ref_ID] = [Extent2].[ID]) AND ([Extent1].[Ref_ID2] = [Extent2].[ID2])

เจฏเจพเจจเฉ€, เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡, LINQ เจ•เจฟเจŠเจฐเฉ€ เจจเฉ‡ MS SQL เจธเจฐเจตเจฐ DBMS เจฒเจˆ เจ‡เฉฑเจ• SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจพเจซเจผเฉ€ เจšเฉฐเจ—เฉ€ เจคเจฐเฉเจนเจพเจ‚ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจนเฉˆเฅค

เจ†เจ“ เจนเฉเจฃ LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจตเจฟเฉฑเจš AND เจ•เฉฐเจกเฉ€เจธเจผเจจ เจจเฉ‚เฉฐ OR เจตเจฟเฉฑเจš เจฌเจฆเจฒเฉ€เจ:

LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                || (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

เจ…เจคเฉ‡ เจ†เจ“ เจ†เจชเจฃเฉ€ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจฒเจพเจ‚เจš เจ•เจฐเฉ€เจเฅค

เจ•เจฎเจพเจ‚เจก เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจŸเจพเจˆเจฎ 30 เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจคเฉ‹เจ‚ เจตเฉฑเจง เจนเฉ‹เจฃ เจ•เจพเจฐเจจ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจ—เจฒเจคเฉ€ เจจเจพเจฒ เจ•เฉเจฐเฉˆเจธเจผ เจนเฉ‹ เจœเจพเจตเฉ‡เจ—เจพ:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ LINQ เจฆเฉเจ†เจฐเจพ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจจเฉ‚เฉฐ เจฆเฉ‡เจ–เจฆเฉ‡ เจนเฉ‹:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚
, เจซเจฟเจฐ เจคเฉเจธเฉ€เจ‚ เจ‡เจน เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจ•เจฟ เจšเฉ‹เจฃ เจฆเฉ‹ เจธเฉˆเฉฑเจŸเจพเจ‚ (เจŸเฉ‡เจฌเจฒ) เจฆเฉ‡ เจ•เจพเจฐเจŸเฉ‡เจธเจผเฉ€เจ…เจจ เจ‰เจคเจชเจพเจฆ เจฆเฉเจ†เจฐเจพ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ:

เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

SELECT TOP (1000) 
    [Extent1].[Ref_ID] AS [Ref_ID], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Name] AS [Name1]
    FROM  [dbo].[Customer] AS [Extent1]
    CROSS JOIN [dbo].[Ref] AS [Extent2]
    WHERE [Extent1].[Ref_ID] = [Extent2].[ID] OR [Extent1].[Ref_ID2] = [Extent2].[ID2]

เจ†เจ“ LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจจเฉ‚เฉฐ เจนเฉ‡เจ เจพเจ‚ เจฒเจฟเจ–เฉ‡ เจ…เจจเฉเจธเจพเจฐ เจฆเฉเจฌเจพเจฐเจพ เจฒเจฟเจ–เฉ€เจ:

เจ…เจจเฉเจ•เฉ‚เจฒเจฟเจค LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

var query = (from e1 in db.Customer
                   join e2 in db.Ref
                   on e1.Ref_ID equals e2.ID
                   select new { Data1 = e1.Name, Data2 = e2.Name }).Union(
                        from e1 in db.Customer
                        join e2 in db.Ref
                        on e1.Ref_ID2 equals e2.ID2
                        select new { Data1 = e1.Name, Data2 = e2.Name });

เจซเจฟเจฐ เจธเจพเจจเฉ‚เฉฐ เจนเฉ‡เจ  เจฆเจฟเฉฑเจคเฉ€ SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฎเจฟเจฒเจฆเฉ€ เจนเฉˆ:

SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

SELECT 
    [Limit1].[C1] AS [C1], 
    [Limit1].[C2] AS [C2], 
    [Limit1].[C3] AS [C3]
    FROM ( SELECT DISTINCT TOP (1000) 
        [UnionAll1].[C1] AS [C1], 
        [UnionAll1].[Name] AS [C2], 
        [UnionAll1].[Name1] AS [C3]
        FROM  (SELECT 
            1 AS [C1], 
            [Extent1].[Name] AS [Name], 
            [Extent2].[Name] AS [Name1]
            FROM  [dbo].[Customer] AS [Extent1]
            INNER JOIN [dbo].[Ref] AS [Extent2] ON [Extent1].[Ref_ID] = [Extent2].[ID]
        UNION ALL
            SELECT 
            1 AS [C1], 
            [Extent3].[Name] AS [Name], 
            [Extent4].[Name] AS [Name1]
            FROM  [dbo].[Customer] AS [Extent3]
            INNER JOIN [dbo].[Ref] AS [Extent4] ON [Extent3].[Ref_ID2] = [Extent4].[ID2]) AS [UnionAll1]
    )  AS [Limit1]

เจนเจพเจ, LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›เจพเจ‚ เจตเจฟเฉฑเจš เจธเจฟเจฐเจซเจผ เจ‡เฉฑเจ• เจœเฉ‹เฉœเจจ เจฆเฉ€ เจธเจผเจฐเจค เจนเฉ‹ เจธเจ•เจฆเฉ€ เจนเฉˆ, เจ‡เจธเจฒเจˆ เจ‡เฉฑเจฅเฉ‡ เจนเจฐเฉ‡เจ• เจธเจผเจฐเจค เจฒเจˆ เจฆเฉ‹ เจธเจตเจพเจฒเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ…เจคเฉ‡ เจซเจฟเจฐ เจ•เจคเจพเจฐเจพเจ‚ เจตเจฟเฉฑเจš เจกเฉเจชเจฒเฉ€เจ•เฉ‡เจŸ เจจเฉ‚เฉฐ เจนเจŸเจพเจ‰เจฃ เจฒเจˆ เจฏเฉ‚เจจเฉ€เจ…เจจ เจฆเฉเจ†เจฐเจพ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจœเฉ‹เฉœ เจ•เฉ‡ เจ‡เฉฑเจ• เจฌเจฐเจพเจฌเจฐ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจนเฉˆเฅค
เจนเจพเจ‚, เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›เจพเจ‚ เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡ เจ—เฉˆเจฐ-เจฌเจฐเจพเจฌเจฐ เจนเฉ‹เจฃเจ—เฉ€เจ†เจ‚, เจ‡เจธ เจ—เฉฑเจฒ เจจเฉ‚เฉฐ เจงเจฟเจ†เจจ เจตเจฟเฉฑเจš เจฐเฉฑเจ–เจฆเฉ‡ เจนเฉ‹เจ เจ•เจฟ เจชเฉ‚เจฐเฉ€ เจกเฉเจชเจฒเฉ€เจ•เฉ‡เจŸ เจ•เจคเจพเจฐเจพเจ‚ เจตเจพเจชเจธ เจ•เฉ€เจคเฉ€เจ†เจ‚ เจœเจพ เจธเจ•เจฆเฉ€เจ†เจ‚ เจนเจจเฅค เจนเจพเจฒเจพเจ‚เจ•เจฟ, เจ…เจธเจฒ เจœเจผเจฟเฉฐเจฆเจ—เฉ€ เจตเจฟเฉฑเจš, เจชเฉ‚เจฐเฉ€ เจกเฉเจชเจฒเฉ€เจ•เฉ‡เจŸ เจฒเจพเจˆเจจเจพเจ‚ เจฆเฉ€ เจœเจผเจฐเฉ‚เจฐเจค เจจเจนเฉ€เจ‚ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ เจ…เจคเฉ‡ เจฒเฉ‹เจ• เจ‰เจจเฉเจนเจพเจ‚ เจคเฉ‹เจ‚ เจ›เฉเจŸเจ•เจพเจฐเจพ เจชเจพเจ‰เจฃ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเจฆเฉ‡ เจนเจจ.

เจ†เจ‰ เจนเฉเจฃ เจ‡เจนเจจเจพเจ‚ เจฆเฉ‹ เจธเจตเจพเจฒเจพเจ‚ เจฆเฉ‡ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจชเจฒเจพเจจ เจฆเฉ€ เจคเฉเจฒเจจเจพ เจ•เจฐเฉ€เจ:

  1. CROSS JOIN เจฒเจˆ เจ”เจธเจค เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจŸเจพเจˆเจฎ 195 เจธเจ•เจฟเฉฐเจŸ เจนเฉˆ:
    MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚
  2. INNER JoIN-UNION เจฒเจˆ เจ”เจธเจค เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจธเจฎเจพเจ‚ 24 เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจคเฉ‹เจ‚ เจ˜เฉฑเจŸ เจนเฉˆ:
    MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚

เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจจเจคเฉ€เจœเจฟเจ†เจ‚ เจคเฉ‹เจ‚ เจฆเฉ‡เจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจฒเฉฑเจ–เจพเจ‚ เจฐเจฟเจ•เจพเจฐเจกเจพเจ‚ เจตเจพเจฒเฉ€เจ†เจ‚ เจฆเฉ‹ เจŸเฉ‡เจฌเจฒเจพเจ‚ เจฒเจˆ, เจ…เจจเฉเจ•เฉ‚เจฒเจฟเจค LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ—เฉˆเจฐ-เจ…เจจเฉเจ•เฉ‚เจฒเจฟเจค เจจเจพเจฒเฉ‹เจ‚ เจ•เจˆ เจ—เฉเจฃเจพ เจคเฉ‡เจœเจผ เจนเฉˆเฅค

เจธเจผเจฐเจคเจพเจ‚ เจตเจฟเฉฑเจš AND เจฆเฉ‡ เจตเจฟเจ•เจฒเจช เจฒเจˆ, เจซเจพเจฐเจฎ เจฆเฉ€ เจ‡เฉฑเจ• LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›:

LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›

var query = from e1 in db.Customer
                            from e2 in db.Ref
                            where (e1.Ref_ID == e2.ID)
                                 && (e1.Ref_ID2 == e2.ID2)
                            select new { Data1 = e1.Name, Data2 = e2.Name };

เจธเจนเฉ€ SQL เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฒเจ—เจญเจ— เจนเจฎเฉ‡เจธเจผเจพเจ‚ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจœเจพเจตเฉ‡เจ—เฉ€, เจœเฉ‹ เจ”เจธเจคเจจ 1 เจธเจ•เจฟเฉฐเจŸ เจตเจฟเฉฑเจš เจšเฉฑเจฒเฉ‡เจ—เฉ€:

MS SQL เจธเจฐเจตเจฐ เจฒเจˆ C#.NET เจตเจฟเฉฑเจš LINQ เจธเจตเจพเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚
เจ‡เฉฑเจ• เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฆเฉ€ เจฌเจœเจพเจ LINQ เจคเฉ‹เจ‚ เจ†เจฌเจœเฉˆเจ•เจŸ เจนเฉ‡เจฐเจพเจซเฉ‡เจฐเฉ€ เจฒเจˆ เจตเฉ€:

LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› (เจชเจนเจฟเจฒเจพ เจตเจฟเจ•เจฒเจช)

var query = from e1 in seq1
                            from e2 in seq2
                            where (e1.Key1==e2.Key1)
                               && (e1.Key2==e2.Key2)
                            select new { Data1 = e1.Data, Data2 = e2.Data };

เจคเฉเจธเฉ€เจ‚ เจ‡เฉฑเจ• เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจœเจฟเจตเฉ‡เจ‚:

LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› (เจชเจนเจฟเจฒเจพ เจตเจฟเจ•เจฒเจช)

var query = from e1 in seq1
                            join e2 in seq2
                            on new { e1.Key1, e1.Key2 } equals new { e2.Key1, e2.Key2 }
                            select new { Data1 = e1.Data, Data2 = e2.Data };

เจœเจฟเฉฑเจฅเฉ‡:

เจฆเฉ‹ เจเจฐเฉ‡ เจฆเฉ€ เจชเจฐเจฟเจญเจพเจธเจผเจพ

Para[] seq1 = new[] { new Para { Key1 = 1, Key2 = 2, Data = "777" }, new Para { Key1 = 2, Key2 = 3, Data = "888" }, new Para { Key1 = 3, Key2 = 4, Data = "999" } };
Para[] seq2 = new[] { new Para { Key1 = 1, Key2 = 2, Data = "777" }, new Para { Key1 = 2, Key2 = 3, Data = "888" }, new Para { Key1 = 3, Key2 = 5, Data = "999" } };

, เจ…เจคเฉ‡ เจชเฉˆเจฐเจพ เจ•เจฟเจธเจฎ เจจเฉ‚เฉฐ เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจชเจฐเจฟเจญเจพเจธเจผเจฟเจค เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ:

เจชเฉˆเจฐเจพ เจŸเจพเจˆเจช เจชเจฐเจฟเจญเจพเจธเจผเจพ

class Para
{
        public int Key1, Key2;
        public string Data;
}

เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚, เจ…เจธเฉ€เจ‚ MS SQL เจธเจฐเจตเจฐ เจฒเจˆ LINQ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›เจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ•เฉเจ เจชเจนเจฟเจฒเฉ‚เจ†เจ‚ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เฉ€เจคเฉ€เฅค

เจฌเจฆเจ•เจฟเจธเจฎเจคเฉ€ เจจเจพเจฒ, เจ‡เฉฑเจฅเฉ‹เจ‚ เจคเฉฑเจ• เจ•เจฟ เจคเจœเจฐเจฌเฉ‡เจ•เจพเจฐ เจ…เจคเฉ‡ เจฎเฉ‹เจนเจฐเฉ€ .NET เจกเจฟเจตเฉˆเจฒเจชเจฐ เจ‡เจน เจญเฉเฉฑเจฒ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจ•เจฟ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เจน เจธเจฎเจเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจ•เจฟ เจ‰เจน เจœเฉ‹ เจจเจฟเจฐเจฆเฉ‡เจธเจผ เจตเจฐเจคเจฆเฉ‡ เจนเจจ เจ‰เจน เจชเจฐเจฆเฉ‡ เจฆเฉ‡ เจชเจฟเฉฑเจ›เฉ‡ เจ•เฉ€ เจ•เจฐเจฆเฉ‡ เจนเจจเฅค เจจเจนเฉ€เจ‚ เจคเจพเจ‚, เจ‰เจน เจธเฉฐเจฐเจšเจจเจพเจ•เจพเจฐ เจฌเจฃ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ เจ…เจคเฉ‡ เจธเจพเจซเจŸเจตเฉ‡เจ…เจฐ เจนเฉฑเจฒ เจจเฉ‚เฉฐ เจธเจ•เฉ‡เจฒ เจ•เจฐเจจ เจตเฉ‡เจฒเฉ‡ เจ…เจคเฉ‡ เจฌเจพเจนเจฐเฉ€ เจตเจพเจคเจพเจตเจฐเจฃ เจฆเฉ€เจ†เจ‚ เจธเจฅเจฟเจคเฉ€เจ†เจ‚ เจตเจฟเฉฑเจš เจฎเจพเจฎเฉ‚เจฒเฉ€ เจคเจฌเจฆเฉ€เจฒเฉ€เจ†เจ‚ เจฆเฉ‡ เจจเจพเจฒ เจญเจตเจฟเฉฑเจ– เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจŸเจพเจˆเจฎ เจฌเฉฐเจฌ เจฒเจ—เจพ เจธเจ•เจฆเฉ‡ เจนเจจเฅค

เจ‡เฉฑเจ• เจธเฉฐเจ–เฉ‡เจช เจธเจฎเฉ€เจ–เจฟเจ† เจตเฉ€ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจ‡เฉฑเจฅเฉ‡.

เจŸเฉˆเจธเจŸ เจฒเจˆ เจธเจฐเฉ‹เจค - เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจ–เฉเจฆ, เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจŸเฉ‡เจฌเจฒเจพเจ‚ เจฆเฉ€ เจฐเจšเจจเจพ, เจ…เจคเฉ‡ เจจเจพเจฒ เจนเฉ€ เจ‡เจนเจจเจพเจ‚ เจŸเฉ‡เจฌเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจกเฉ‡เจŸเจพ เจจเจพเจฒ เจญเจฐเจจเจพ เจธเจฅเจฟเจค เจนเฉˆ เจ‡เฉฑเจฅเฉ‡.
เจ‡เจธ เจฐเจฟเจชเฉ‹เจœเจผเจŸเจฐเฉ€ เจตเจฟเฉฑเจš, เจชเจฒเจพเจจ เจซเฉ‹เจฒเจกเจฐ เจตเจฟเฉฑเจš, OR เจธเจผเจฐเจคเจพเจ‚ เจจเจพเจฒ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ›เจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฒเจˆ เจฏเฉ‹เจœเจจเจพเจตเจพเจ‚ เจนเจจเฅค

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹