αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

LINQ αž”αžΆαž“αž”αž‰αŸ’αž…αžΌαž› .NET αž‡αžΆαž—αžΆαžŸαžΆαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž‘αž·αž“αŸ’αž“αž“αŸαž™αžαŸ’αž˜αžΈαžŠαŸαž˜αžΆαž“αž’αžΆαž“αž»αž—αžΆαž–αŸ” LINQ αž‘αŸ… SQL αžŠαŸ‚αž›αž‡αžΆαž•αŸ’αž“αŸ‚αž€αž˜αž½αž™αž“αŸƒαžœαžΆαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αž‘αŸ†αž“αžΆαž€αŸ‹αž‘αŸ†αž“αž„αž™αŸ‰αžΆαž„αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž‡αžΆαž˜αž½αž™ DBMS αžŠαŸ„αž™αž”αŸ’αžšαžΎαž§αž‘αžΆαž αžšαžŽαŸ Entity Framework αŸ” αž‘αŸ„αŸ‡αž‡αžΆαž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αž€αžΆαžšαž”αŸ’αžšαžΎαžœαžΆαž‡αžΆαž‰αžΉαž€αž‰αžΆαž”αŸ‹ αž’αŸ’αž“αž€αž’αž—αž·αžœαžŒαŸ’αžαž“αŸαž—αŸ’αž›αŸαž…αž˜αžΎαž›αžαžΆαžαžΎαž”αŸ’αžšαž—αŸαž‘αž“αŸƒαžŸαŸ†αžŽαž½αžš SQL αž”αŸ’αžšαž—αŸαž‘αžŽαžΆαžŠαŸ‚αž›αž’αŸ’αž“αž€αž•αŸ’αžαž›αŸ‹αžŸαŸαžœαžΆαžŠαŸ‚αž›αž’αžΆαž…αžŸαž½αžšαž”αžΆαž“ αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ Entity Framework αž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαŸ”

αžŸαžΌαž˜αž€αŸ’αžšαž‘αŸαž€αž˜αžΎαž›αž…αŸ†αžŽαž»αž…αžŸαŸ†αžαžΆαž“αŸ‹αž–αžΈαžšαžŠαŸ„αž™αž”αŸ’αžšαžΎαž§αž‘αžΆαž αžšαžŽαŸαž˜αž½αž™αŸ”
αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŠαžΌαž…αŸ’αž“αŸαŸ‡ αž”αž„αŸ’αž€αžΎαž Test database αž“αŸ…αž€αŸ’αž“αž»αž„ SQL Server αž αžΎαž™αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αž–αžΈαžšαž“αŸ…αž€αŸ’αž“αž»αž„αžœαžΆαžŠαŸ„αž™αž”αŸ’αžšαžΎαžŸαŸ†αžŽαž½αžšαžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„

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

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž…αžΌαžšαž™αžΎαž„αž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„ Ref αžŠαŸ„αž™αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ’αž‚αŸ’αžšαžΈαž”αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

αž€αžΆαžšαž”αŸ†αž–αŸαž‰αžαžΆαžšαžΆαž„αž™αŸ„αž„

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 αž›αžΆαž“αž‡αž½αžšαŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡αž“αŸ…αž€αŸ’αž“αž»αž„ Visual Studio αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž”αž„αŸ’αž€αžΎαžαž‚αž˜αŸ’αžšαŸ„αž„ Visual C# Console App (.NET Framework) αžŸαžΆαž€αž›αŸ’αž”αž„αŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€ αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž”αž“αŸ’αžαŸ‚αž˜αž”αžŽαŸ’αžŽαžΆαž›αŸαž™αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ Entity Framework αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαž’αž“αŸ’αžαžšαž€αž˜αŸ’αž˜αž‡αžΆαž˜αž½αž™αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™αŸ”
αžŠαžΎαž˜αŸ’αž”αžΈαž”αž“αŸ’αžαŸ‚αž˜αžœαžΆ αž…αž»αž…αž€αžŽαŸ’αžŠαž»αžšαžŸαŸ’αžŠαžΆαŸ†αž›αžΎαž‚αž˜αŸ’αžšαŸ„αž„ αž αžΎαž™αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž€αž‰αŸ’αž…αž”αŸ‹ NuGet αž–αžΈαž˜αŸ‰αžΊαž“αž»αž™αž”αžšαž·αž”αž‘αŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž“αŸ…αž€αŸ’αž“αž»αž„αž”αž„αŸ’αž’αž½αž…αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž€αž‰αŸ’αž…αž”αŸ‹ NuGet αžŠαŸ‚αž›αž”αž„αŸ’αž αžΆαž‰ αžŸαžΌαž˜αž”αž‰αŸ’αž…αžΌαž›αž–αžΆαž€αŸ’αž™ "Entity Framework" αž“αŸ…αž€αŸ’αž“αž»αž„αž”αž„αŸ’αž’αž½αž…αžŸαŸ’αžœαŸ‚αž„αžšαž€ αž αžΎαž™αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž€αž‰αŸ’αž…αž”αŸ‹ Entity Framework αž αžΎαž™αžŠαŸ†αž‘αžΎαž„αžœαžΆαŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž“αŸ…αž€αŸ’αž“αž»αž„αž―αž€αžŸαžΆαžš App.config αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž”αž·αž‘αž’αžΆαžαž» configSections αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž”αž“αŸ’αžαŸ‚αž˜αž”αŸ’αž›αž»αž€αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

<connectionStrings>
    <add name="DBConnection" connectionString="data source=ИМЯ_Π­ΠšΠ—Π•ΠœΠŸΠ›Π―Π Π_MSSQL;Initial Catalog=TEST;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>

αž“αŸ…αž€αŸ’αž“αž»αž„ connectionString αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž”αž‰αŸ’αž…αžΌαž›αžαŸ’αžŸαŸ‚αžαž—αŸ’αž‡αžΆαž”αŸ‹αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡αžŸαžΌαž˜αž”αž„αŸ’αž€αžΎαžαž…αŸ†αžŽαž»αž…αž”αŸ’αžšαž‘αžΆαž€αŸ‹ 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. αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαžαŸ’αž“αžΆαž€αŸ‹ Ref
    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; }
    }
}

αž™αžΎαž„αž”αžΆαž“αž‘αž‘αž½αž›αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αžŠαŸ‚αž›αžαŸ’αžšαŸ€αž˜αžšαž½αž…αž‡αžΆαžŸαŸ’αžšαŸαž…αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αž‡αžΆαž˜αž½αž™ LINQ αž‘αŸ… SQL αžαžΆαž˜αžšαž™αŸˆ EF αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL ServerαŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αž₯αž‘αžΌαžœαž”αž‰αŸ’αž…αžΌαž›αž€αžΌαžŠαžαžΆαž„αž€αŸ’αžšαŸ„αž˜αž‘αŸ…αž€αŸ’αž“αž»αž„αž―αž€αžŸαžΆαžš 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 αž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαžŸαŸ†αžŽαž½αžš SQL αž‘αŸ…αž€αžΆαž“αŸ‹ MS SQL Server DBMS αž”αžΆαž“αž™αŸ‰αžΆαž„αž›αŸ’αž’αŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž…αžΌαžšαž™αžΎαž„αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž›αž€αŸ’αžαžαžŽαŸ’αžŒ AND αž‘αŸ… OR αž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸ†αžŽαž½αžš 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 };

αž αžΎαž™αžŸαžΌαž˜αž”αžΎαž€αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžšαž”αžŸαŸ‹αž™αžΎαž„αž˜αŸ’αžαž„αž‘αŸ€αžαŸ”

αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž“αžΉαž„αž‚αžΆαŸ†αž„αžŠαŸ„αž™αž˜αžΆαž“αž€αŸ†αž αž»αžŸαžŠαŸ„αž™αžŸαžΆαžšαžαŸ‚αž–αŸαž›αžœαŸαž›αžΆαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆαž›αžΎαžŸαž–αžΈ 30 αžœαž·αž“αžΆαž‘αžΈαŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž€αŸ’αžšαž‘αŸαž€αž˜αžΎαž›αžŸαŸ†αžŽαž½αžšαžŠαŸ‚αž›αž”αž„αŸ’αž€αžΎαžαžŠαŸ„αž™ LINQαŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server
αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž’αŸ’αž“αž€αž’αžΆαž…αž”αŸ’αžšαžΆαž€αžŠαžαžΆαž€αžΆαžšαž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸαž€αžΎαžαž‘αžΎαž„αžαžΆαž˜αžšαž™αŸˆαž•αž›αž·αžαž•αž› Cartesian αž–αžΈαžšαžˆαž»αž (αžαžΆαžšαžΆαž„):

αž”αžΆαž“β€‹αž”αž„αŸ’αž€αžΎαžβ€‹αžŸαŸ†αžŽαž½αžš 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]

Alas, αž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸ†αžŽαž½αžš LINQ αž’αžΆαž…αž˜αžΆαž“αž›αž€αŸ’αžαžαžŽαŸ’αžŒαž…αžΌαž›αžšαž½αž˜αžαŸ‚αž˜αž½αž™αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡ αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž“αŸ…αž‘αžΈαž“αŸαŸ‡αžœαžΆαž’αžΆαž…αž’αŸ’αžœαžΎαž‘αŸ…αž”αžΆαž“αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŸαŸ†αžŽαž½αžšαžŸαž˜αž˜αžΌαž›αžŠαŸ„αž™αž”αŸ’αžšαžΎαžŸαŸ†αžŽαž½αžšαž–αžΈαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž›αž€αŸ’αžαžαžŽαŸ’αžŒαž“αžΈαž˜αž½αž™αŸ— αž αžΎαž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž”αž‰αŸ’αž…αžΌαž›αž‚αŸ’αž“αžΆαžαžΆαž˜αžšαž™αŸˆ Union αžŠαžΎαž˜αŸ’αž”αžΈαž›αž»αž”αž›αŸαžαžŸαŸ’αž‘αž½αž“αž€αŸ’αž“αž»αž„αž…αŸ†αžŽαŸ„αž˜αž‡αž½αžšαžŠαŸαž€αŸ”
αž”αžΆαž‘/αž…αžΆαžŸ αžŸαŸ†αžŽαž½αžšαž‡αžΆαž‘αžΌαž‘αŸ…αž“αžΉαž„αž˜αž·αž“αžŸαž˜αž˜αžΌαž›αž‘αŸ αžŠαŸ„αž™αž‚αž·αžαž‚αžΌαžšαžαžΆαž‡αž½αžšαžŠαŸ‚αž›αžŸαŸ’αž‘αž½αž“αž–αŸαž‰αž›αŸαž‰αž’αžΆαž…αž“αžΉαž„αžαŸ’αžšαžΌαžœαž”αž‰αŸ’αž‡αžΌαž“αž˜αž€αžœαž·αž‰αŸ” αž‘αŸ„αŸ‡αž‡αžΆαž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™αž“αŸ…αž€αŸ’αž“αž»αž„αž‡αžΈαžœαž·αžαž–αž·αžαž”αž“αŸ’αž‘αžΆαžαŸ‹αžŸαŸ’αž‘αž½αž“αž–αŸαž‰αž›αŸαž‰αž˜αž·αž“αž…αžΆαŸ†αž”αžΆαž…αŸ‹αž‘αŸαž αžΎαž™αž˜αž“αž»αžŸαŸ’αžŸαž–αŸ’αž™αžΆαž™αžΆαž˜αž€αž˜αŸ’αž…αžΆαžαŸ‹αž–αž½αž€αž‚αŸαŸ”

αž₯αž‘αžΌαžœαž“αŸαŸ‡ αž…αžΌαžšαž™αžΎαž„αž”αŸ’αžšαŸ€αž”αž’αŸ€αž”αž•αŸ‚αž“αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž“αŸƒαžŸαŸ†αžŽαž½αžšαž‘αžΆαŸ†αž„αž–αžΈαžšαž“αŸαŸ‡αŸ–

  1. αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ CROSS JOIN αž–αŸαž›αžœαŸαž›αžΆαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž‡αžΆαž˜αž’αŸ’αž™αž˜αž‚αžΊ 195 αžœαž·αž“αžΆαž‘αžΈαŸ–
    αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server
  2. αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ INNER JOIN-UNION αž–αŸαž›αžœαŸαž›αžΆαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž‡αžΆαž˜αž’αŸ’αž™αž˜αž‚αžΊαžαž·αž…αž‡αžΆαž„ 24 αžœαž·αž“αžΆαž‘αžΈαŸ–
    αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server

αžŠαžΌαž…αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž˜αžΎαž›αžƒαžΎαž‰αž–αžΈαž›αž‘αŸ’αž’αž•αž› αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαžΆαžšαžΆαž„αž–αžΈαžšαžŠαŸ‚αž›αž˜αžΆαž“αž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆαžšαžΆαž”αŸ‹αž›αžΆαž“ αžŸαŸ†αžŽαž½αžš 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 αžœαž·αž“αžΆαž‘αžΈαŸ–

αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž“αŸƒαž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž“αŸ…αž€αŸ’αž“αž»αž„ C#.NET αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ MS SQL Server
αž•αž„αžŠαŸ‚αžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ LINQ to Objects manipulations αž‡αŸ†αž“αž½αžŸαž±αŸ’αž™αžŸαŸ†αžŽαž½αžšαžŠαžΌαž…αž‡αžΆαŸ–

αžŸαŸ†αžŽαž½αžš LINQ (αž‡αž˜αŸ’αžšαžΎαžŸαž‘αžΈ 1)

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 (αž‡αž˜αŸ’αžšαžΎαžŸαž‘αžΈ 2)

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

αž αžΎαž™αž”αŸ’αžšαž—αŸαž‘ Para αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αŸ–

αž“αž·αž™αž˜αž“αŸαž™β€‹αž”αŸ’αžšαž—αŸαž‘ Para

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

αžŠαžΌαž…αŸ’αž“αŸαŸ‡ αž™αžΎαž„αž”αžΆαž“αž–αž·αž“αž·αžαŸ’αž™αž‘αž·αžŠαŸ’αž‹αž—αžΆαž–αž˜αž½αž™αž…αŸ†αž“αž½αž“αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αžŸαŸ†αžŽαž½αžš LINQ αž‘αŸ…αž€αžΆαž“αŸ‹ MS SQL Server αŸ”

αž‡αžΆαž’αž€αž»αžŸαž› αžŸαžΌαž˜αŸ’αž”αžΈαžαŸ‚αž’αŸ’αž“αž€αž’αž—αž·αžœαžŒαŸ’αžαž“αŸ .NET αžŠαŸ‚αž›αž˜αžΆαž“αž”αž‘αž–αž·αžŸαŸ„αž’αž“αŸ αž“αž·αž„αžˆαžΆαž“αž˜αž»αžαž‚αŸαž—αŸ’αž›αŸαž…αžαžΆαž–αž½αž€αž‚αŸαžαŸ’αžšαžΌαžœαž™αž›αŸ‹αž–αžΈαž’αŸ’αžœαžΈαžŠαŸ‚αž›αž€αžΆαžšαžŽαŸ‚αž“αžΆαŸ†αžŠαŸ‚αž›αž–αž½αž€αž‚αŸαž”αŸ’αžšαžΎαž’αŸ’αžœαžΎαž“αŸ…αž–αžΈαž€αŸ’αžšαŸ„αž™αž†αžΆαž€αŸ” αž”αžΎαž˜αž·αž“αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž‘αŸ αž–αž½αž€αž‚αŸαž€αŸ’αž›αžΆαž™αž‡αžΆαž’αŸ’αž“αž€αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ αž αžΎαž™αž’αžΆαž…αžŠαžΆαŸ†αž‚αŸ’αžšαžΆαž”αŸ‹αž”αŸ‚αž€αž–αŸαž›αžœαŸαž›αžΆαž“αžΆαž–αŸαž›αž’αž“αžΆαž‚αž αž‘αžΆαŸ†αž„αž“αŸ…αž–αŸαž›αž’αŸ’αžœαžΎαž˜αžΆαžαŸ’αžšαžŠαŸ’αž‹αžΆαž“αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ αž“αž·αž„αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžαž·αž…αžαž½αž…αž“αŸ…αž€αŸ’αž“αž»αž„αž›αž€αŸ’αžαžαžŽαŸ’αžŒαž”αžšαž·αžŸαŸ’αžαžΆαž“αžαžΆαž„αž€αŸ’αžšαŸ…αŸ”

αž€αžΆαžšαž–αž·αž“αž·αžαŸ’αž™αž‘αžΎαž„αžœαž·αž‰αžαŸ’αž›αžΈαž˜αž½αž™αž€αŸαžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αž“αž»αžœαžαŸ’αžαž•αž„αžŠαŸ‚αžšαŸ” αž“αŸ…αž‘αžΈαž“αŸαŸ‡.

αž”αŸ’αžšαž—αž–αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αž - αž‚αž˜αŸ’αžšαŸ„αž„αžαŸ’αž›αž½αž“αžœαžΆ αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžαžΆαžšαžΆαž„αž“αŸ…αž€αŸ’αž“αž»αž„αž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž‘αž·αž“αŸ’αž“αž“αŸαž™ TEST αž€αŸαžŠαžΌαž…αž‡αžΆαž€αžΆαžšαž”αŸ†αž–αŸαž‰αžαžΆαžšαžΆαž„αž‘αžΆαŸ†αž„αž“αŸαŸ‡αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž‘αž·αž“αŸ’αž“αž“αŸαž™αž˜αžΆαž“αž‘αžΈαžαžΆαŸ†αž„αž“αŸ… αž“αŸ…αž‘αžΈαž“αŸαŸ‡.
αž•αž„αžŠαŸ‚αžšαž“αŸ…αž€αŸ’αž“αž»αž„αžƒαŸ’αž›αžΆαŸ†αž„αž“αŸαŸ‡ αž“αŸ…αž€αŸ’αž“αž»αž„αžαžαž•αŸ‚αž“αž€αžΆαžš αž˜αžΆαž“αž•αŸ‚αž“αž€αžΆαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ†αžŽαž½αžšαž‡αžΆαž˜αž½αž™αž›αž€αŸ’αžαžαžŽαŸ’αžŒ OR αŸ”

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹