Özgür Özvarış

Bir yazılımcının kırık dökük dünyası

Msql foreign key arka planı

clock Haziran 28, 2016 17:11 by author OzgurOzvaris

Merhaba ,

Bu günki yazımızda mssql de foreign key ile ilgili bir kaç script paylayacağım. Öncelikle bu konu nerden çıktı diye düşünebilirsiniz çıkış noktası entityframework (EF) te (Database First) alter table ile değişiklik yapılan bir tablonun EF foreign key (FK) bağlantıları uçtu. Neden uçtuğunu anlamak için EF kün tablo eklerken kullandığı sql cümlelerini  profiler aracalığı ile  incelemek ve süzerek boş dönen sql cümlesini tespit etmek durumuda kaldım. Baştan söyleyim çok zor bir yöntem oldu ancak sonuçta sorunu bulmamı sağladı.

Baştan başlar isek öncelilkle birbiri ile foreign key bağlantısı kuracağımız iki tablo açalım

CREATE TABLE Table_Ttmp 

(
Table_T_ID numeric(12, 0) IDENTITY(1,1),
PRIMARY KEY (Table_T_ID),


)

CREATE TABLE Table_Mtmp 

(
Table_M_ID numeric(12, 0) IDENTITY(1,1),
Table_T_ID numeric(12, 0) NOT NULL,
PRIMARY KEY (Table_M_ID),
--FOREIGN KEY (Table_T_ID) REFERENCES Table_Ttmp ,  

)

Bir foreign key constraint eklemek için standart sql cümlesini çalıştırarak devam edelim. (Yukarıdaki scriptte aslında FK oluşturma ile ilgili satır commentli. Bu satırıda aynı işlemi yapar.)

ALTER TABLE dbo.Table_Mtmp ADD CONSTRAINT
FK_Table_Mtmp_Table_Ttmp FOREIGN KEY
(
Table_M_ID
) REFERENCES dbo.Table_Ttmp
(
Table_T_ID
) ON UPDATE  NO ACTION 
 ON DELETE  NO ACTION

Üçüncü bir FK oluşturma yöntemide Sql Server Management Studio (SQLMS) aracılığı ile tabloda design diyerek ve Relations ları seçerek FK oluşturmak. Burada kaydet demeden oluşturulan scripte bakarsanız yukarıda ki scriptin aynısını oluşturduğunu görecektsiniz

Yukarıdaki üç yöntemden herhabgi biri  ile FK ilişkilsi eklediğinizde MSSQL iki tablo arasında ilişki kuruyor. Yukarıdaki tabloda anlaşıldığı üzere ilişki Table_Mtmp ile Table_Ttmp arasıdına oluşturulmuş durumda. Table_Ttmp Primary key'in olduğu tablo, Table_Mtmp foreign key'in olduğu tablo.

Buraya kadar anlattıklarımız giriş şimdi öğreneceklerimizin alt yapısını oluşturmak içinde. SQLMS ekranlarıyla geldiğimiz aşamayı görelim. 

 

 

Şimdi asıl paylaşacağım aşamalara geldik.

 

SQLMS yukarıdaki bağlantıyı göstebilmek için şimdi paylaştığım sql cümlesini kullanıyor. Bu scriptin düzgün sonuç vermesi için use ile db niniz seçmeniz gerekiyor...

select Fk.name, Fk.object_id, Fk.is_disabled, Fk.is_not_for_replication, Fk.delete_referential_action, Fk.update_referential_action, 
object_name(Fk.parent_object_id) as Fk_table_name, schema_name(Fk.schema_id) as Fk_table_schema, TbR.name as Pk_table_name, 
schema_name(TbR.schema_id) Pk_table_schema, col_name(Fk.parent_object_id, Fk_Cl.parent_column_id) as Fk_col_name, 
col_name(Fk.referenced_object_id, Fk_Cl.referenced_column_id) as Pk_col_name, Fk_Cl.constraint_column_id, Fk.is_not_trusted 
from sys.foreign_keys Fk 
left outer join sys.tables TbR on TbR.object_id = Fk.referenced_object_id 
inner join sys.foreign_key_columns Fk_Cl on Fk_Cl.constraint_object_id = Fk.object_id 

where	Fk.parent_object_id = object_id(N'dbo.Table_Mtmp') or Fk.referenced_object_id = object_id(N'dbo.Table_Mtmp')

 

EF ise bu ilişkiyi almak için başka bir sql script kullanıyor. EF Update Database Model dediğinizde ve yeni bir tablo eklemek istediğinizde yada bir tablodaki güncellemeyi almak için silip tekrar eklediğinizde uzunca birkaç sql cümlesi gönderiyor. Bunlardan birtanesi tablolar arasındaki ilişkiyi çekmek için. 359 satırlık bir sql cümlesi olduğu için onu dosya olarak paylaşıyorum. Bunu paylaşma nedenim bir kaynak olması için. Yoksa satır satır bu sql'in ne yaptığını bende bilmiyorum. Ancak biraz sonra açıklayacağım scriptler bu büyük scriptin içinden işlevselliklerine göre seçilerek elde edildi. 

 EFFullScript.txt (16,72 kb)

 

Bu uzunça scriptin çıktısı yukarıda paylaştığım ekran. Burda belirtilen bilgiler Table_Ttmp diye bir tablonun Table_T_ID primary key alnı ile Table_Mtmp tablosunun Table_M_ID ( Doğru bağlantı tabiki Table_T_ID olması gerekiyordu ama test tablosu olduğu için düzeltmedim) kolonu arasında FK_Table_Mtmp2_Table_T isimli (yukarıda SQLMS da aynı isim var)  [dbo][FK_Table_Mtmp2_Table_T] id li (Bu id name'in DB tarafındaki karşılığı) bir ilişki vardır. Bu satır boş gelirse EF association Model de FK ilişkiyi kuramıyor. Bizde de aynen böyle oldu ve FK SQLMS da gözüktüğü halde EF de gözükmüyordu. Bu nedenle sorunu bulmak için bu uzunca scripti incelemeye almak durumunda kaldık. Buda bizi SQL server FK mantığının derinlerine doğru bir yolculuğa çıkardı. Merak eden buradan sonraki aşamayı takip ederek bu derinliğe bizle birlikte gelebilir.

Öncelikle kısaca fikir edinmek için bu uzun sql cümlesinden birkaç kelime edeyim. Bu sql cümlesinin aslında ilk 358 satırı sabit 359. satır yani "WHERE" ile başlayan satır modelinizdeki tablolara göre dinamik olarak tablo filitreleri oluşturuyor. Kodun daha iyi anlaşılabilmesi için 359. satırdan parametre satırını 360'a valularınıda 361'i satırdan itibaren tablo lara göre enterlı olarak yazdım. Şimdi 361. satırı paylaşıyorum.

@p0=N'K14_abc',@p1=N'dbo',@p2=N'Table_Mtmp',
@p3=N'K14_abc',@p4=N'dbo',@p5=N'Table_Ttmp',
@p6=N'K14_abc',@p7=N'dbo',@p8=N'Table_Mtmp',
@p9=N'K14_abc',@p10=N'dbo',@p11=N'Table_Ttmp'

Görüldüğü gibi burada modele eklediğim başta oluşturduğumuz  Table_Mtmp ve Table_Ttmp satırlarımıza ait tekrar etmiş 4 satır mevcut. Eğer buraya bir 3. tablo daha ekleseydik 360. satırdaki where bölümüne ve parametre value bölümüne bu tablolarda eklenmiş olacaktı ancak ana sql cümlesi değişmeyecekti.  Şimdi gelelim bizim tablolarımızdaki ilişkileri alan sql parçasına. Bu aşamadan sonra paylaşacağım sql scriptler bu 359 satırlık bölümden olacak.

Öncelikle iki tablo arasında FK yı ve FK ilişkisinin temel bilgilerini gösteren ve bu ilişkinin "id" değerini üreten parçayı gösterelim. Bu id bir sonraki script'te ilişkinin detaylarını görmemiz için kullanılacak. Son kısımdaki tablo isimleri parametrelerini değiştirerek bu sorguları istediğiniz  tablo için çalıştırabilirsiniz.

SELECT 
--[Join5].[Ordinal] AS [C1], 
--[UnionAll4].[CatalogName] AS [C2], 
--[UnionAll4].[SchemaName] AS [C3], 
--[UnionAll4].[Name] AS [C4], 
--[Join5].[Name1] AS [C5], 
[UnionAll5].[CatalogName] AS [C6], 
[UnionAll5].[SchemaName] AS [C7], 
[UnionAll5].[Name] AS [C8], 
--[Join5].[Name2] AS [C9], 
[Extent2].[Name] AS [Name], 
[Extent1].[Id] AS [Id]--, 
--CASE WHEN ([Extent1].[DeleteRule] = 'CASCADE') THEN cast(1 as bit) WHEN ([Extent1].[DeleteRule] <> 'CASCADE') THEN cast(0 as bit) END AS [C10]
FROM 

	(SELECT
			quotename(rc.CONSTRAINT_SCHEMA) + quotename(rc.CONSTRAINT_NAME) [Id]
			, CAST(rc.UPDATE_RULE as nvarchar(11)) [UpdateRule]
			, CAST(rc.DELETE_RULE as nvarchar(11)) [DeleteRule]
			FROM
			INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
		  ) AS [Extent1]
	INNER JOIN (
			SELECT
			quotename(tc.CONSTRAINT_SCHEMA) + quotename(tc.CONSTRAINT_NAME) [Id]
			, quotename(tc.TABLE_SCHEMA) + quotename(tc.TABLE_NAME) [ParentId]
			,   tc.CONSTRAINT_NAME [Name]
			,   tc.CONSTRAINT_TYPE [ConstraintType]
			,   CAST(CASE tc.IS_DEFERRABLE WHEN 'NO' THEN 0 ELSE 1 END as bit) [IsDeferrable]
			,   CAST(CASE tc.INITIALLY_DEFERRED WHEN 'NO' THEN 0 ELSE 1 END as bit) [IsInitiallyDeferred]
			FROM
			INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
			WHERE tc.TABLE_NAME IS NOT NULL
		  ) AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]


    
	LEFT OUTER JOIN        
	(SELECT 
		3 AS [C1], 
		[Extent13].[Id] AS [Id], 
		[Extent13].[Name] AS [Name], 
		[Extent13].[CatalogName] AS [CatalogName], 
		[Extent13].[SchemaName] AS [SchemaName]
		FROM (
			SELECT
			quotename(TABLE_SCHEMA) + quotename(TABLE_NAME) [Id]
			,   TABLE_CATALOG [CatalogName]
			,   TABLE_SCHEMA [SchemaName]
			,   TABLE_NAME    [Name]
			FROM
			INFORMATION_SCHEMA.TABLES
			WHERE
			TABLE_TYPE = 'BASE TABLE'
		  ) AS [Extent13]
	UNION ALL
		SELECT 
		12 AS [C1], 
		[Extent14].[Id] AS [Id], 
		[Extent14].[Name] AS [Name], 
		[Extent14].[CatalogName] AS [CatalogName], 
		[Extent14].[SchemaName] AS [SchemaName]
		FROM (
			SELECT
			quotename(TABLE_SCHEMA) + quotename(TABLE_NAME) [Id]
			,   TABLE_CATALOG             [CatalogName]
			,   TABLE_SCHEMA              [SchemaName]
			,   TABLE_NAME                [Name]
			,   VIEW_DEFINITION           [ViewDefinition]
			,   CAST( CASE IS_UPDATABLE WHEN 'YES' THEN 1 WHEN 'NO' THEN 0 ELSE 0 END as bit) [IsUpdatable]
			FROM
			INFORMATION_SCHEMA.VIEWS
			WHERE
			NOT (TABLE_SCHEMA = 'dbo'
			AND TABLE_NAME in('syssegments', 'sysconstraints')
			AND SUBSTRING(CAST(SERVERPROPERTY('productversion') as varchar(20)),1,1) = 8)
		  ) AS [Extent14]) AS [UnionAll5] ON (3 = [UnionAll5].[C1]) AND ([Extent2].[ParentId] = [UnionAll5].[Id])
	WHERE 
	(
		
		(
			([UnionAll5].[CatalogName] LIKE '...') AND 
			([UnionAll5].[SchemaName] LIKE 'dbo') AND 
			([UnionAll5].[Name] LIKE 'Table_Mtmp')
		)

		OR 
		(
			([UnionAll5].[CatalogName] LIKE '...') AND 
			([UnionAll5].[SchemaName] LIKE 'dbo') AND 
			([UnionAll5].[Name] LIKE 'Table_Ttmp')
		)
	)

 

Bu scriptin çıktısı şu şekilde olmalı. Eğer Table_Ttmp ninde FK bağlantıları olsaydı onlarda gelecekti

 

 

Şimdi paylaşacaım script ise bu id değerine göre iki tablo arasında hangi kolonlar arasında bu ilişkinin olduğunu gösteriyor

SELECT
[Extent3].[Ordinal] AS [Ordinal], 
0 AS [C1], 
[Extent3].[ConstraintId] AS [ConstraintId], 
6 AS [C2], 
[Extent3].[FromColumnId] AS [FromColumnId], 
6 AS [C3], 
[Extent3].[ToColumnId] AS [ToColumnId]
FROM (
  SELECT
  quotename(FC.CONSTRAINT_SCHEMA) + quotename(FC.CONSTRAINT_NAME) + quotename(cast(FC.ORDINAL_POSITION as nvarchar(30))) [Id]
  ,   quotename(PC.TABLE_SCHEMA) + quotename(PC.TABLE_NAME) + quotename(PC.COLUMN_NAME) [ToColumnId]
  ,   quotename(FC.TABLE_SCHEMA) + quotename(FC.TABLE_NAME) + quotename(FC.COLUMN_NAME) [FromColumnId]
  ,   quotename(FC.CONSTRAINT_SCHEMA) + quotename(FC.CONSTRAINT_NAME) [ConstraintId]
  ,   FC.ORDINAL_POSITION [Ordinal]
  FROM 
	INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC 
	  INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS PC /* PRIMARY KEY COLS*/ ON       
		RC.UNIQUE_CONSTRAINT_SCHEMA = PC.CONSTRAINT_SCHEMA  
		AND      RC.UNIQUE_CONSTRAINT_NAME    = PC.CONSTRAINT_NAME
      INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS FC /* FOREIGN KEY COLS*/ ON       
		RC.CONSTRAINT_SCHEMA = FC.CONSTRAINT_SCHEMA         
		AND      RC.CONSTRAINT_NAME    = FC.CONSTRAINT_NAME 
		AND   PC.ORDINAL_POSITION = FC.ORDINAL_POSITION
) AS [Extent3]

where ('[dbo][FK_Table_Mtmp2_Table_T]' = [ConstraintId])

 

Çıktısı şu şekilde olmalı

 

 

Yukarıdaki çıktıdan anlaşıldığı üzere FromColumnId de gözüken Table_Mtmp tablosunun Table_M_ID kolonu ile ToColumnId de gözüken Table_Ttmp ve Table_T_ID arasında [dbo][FK_Table_Mtmp2_Table_T] idli bir bağlantı bulunmaktadır. Eğer bu satır boş gelirse EF FK ilişkisini (association) kuramıyor.

Aslında amacımıza ulaştık iki tablo arasında ilişkiyi gördük. Ama asıl çözüm sağlayan adım burada başlıyor. Burada satır boş gelirse sorunu nasıl anlayacağız. Çünkü bizde ilişki olduğu halde satır burada boş geliyordu. İşte onun tahlilinide bu script içinden aldığım son script ile paylaşarak yapacağız.

Select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where '[dbo][FK_Table_Mtmp2_Table_T]' =  quotename(CONSTRAINT_SCHEMA) + quotename(CONSTRAINT_NAME) 
Select * from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS where CONSTRAINT_SCHEMA = 'dbo' AND CONSTRAINT_NAME = 'FK_Table_Mtmp2_Table_T'
Select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where CONSTRAINT_SCHEMA = 'dbo' AND CONSTRAINT_NAME = 'PK__Table_Tt__96E7C6DB2B803210'

Ekran Çıktısı

  

Burada artık bu FK ilişkisinin hangi Constraint Name ler ile hangi tablolar arasında kurulduğu net olarak gözüküyor. Scripteki birinci tablo FK sahibi olan Table_Mtmp tablosun ait, ikinci satır PK (Primary key) tablosu ile ilikiliyi kurulan PK ya ait contraint'in isminin saklandığı UNIQUE_CONSTRAINT_NAME kolonunu içeriyor. Üçüncü satır aslında birinci satırla aynı KEY_COLUMN_USAGE Information Schemasına bakıyor ancak artık PK ya ait olan constraint name le bakıyor.

Bizim sorun neydi bari onuda söyliyeyim :) İşte 2 Satırda aldığımız  UNIQUE_CONSTRAINT_NAME PK Contraint name i üçüncü satırda where cümlesine konulunca boş geliyordu. Sebebi meğerse aynı PK değeri üzerinde aynı özelliklere sahip bir index tanımlanmış ve bağlantı PK Contraint Key'i ile değilde bu index ile kurulmuş. O index ise  KEY_COLUMN_USAGE Information Schemasında gözükmediği için EF FK ilişkisini kuramıyordu. O index'i sildik sorun çözüldü. Artık son scriptteki 3 satırda dolu gelmeye başladı :)

 

İyi çalışmalar.



LinqKit Linq dynamic sql parameter

clock Şubat 11, 2016 13:47 by author OzgurOzvaris

Merhaba Arkadaşlar,

Kaynaklar

What is LINQKit?

Dynamically Composing Expression Predicates

How does PredicateBuilder work

linqpad - adding reference to assembly to using custom types

How does LINQPad reference other classes

Building LINQ Queries at Runtime in C#

LinqPad adds an S to the end of every table

Writing Methods and Classes in LINQPad

Entity Framework te Linq ile yapacağınız geliştirmelerde. ilk karşınıza çıkacak zorluklardan bir tanesi dinamik olarak parametre eklemek.

LinqPad malumunuz uzun süredir linq cümleleri geliştirmek için kullanılan bir araç. Gerek database bağlantılı gerekse database bağlantısı olmadan linq sorgularının çıktılarını inceleyebiliryorsunuz. Bu bloğu sanki LinqPad ile ilgili bası basamakları biliyormuşsunuz gibi bazı ön kabullerle başlayacağım. Bu Ön kabuller.

1 - Temel Linq bilgisi

2 - LinqPad download ve install edilmesi

3 - Database connection oluşturulması

Bu ön kabuller üzerinden devam ederek sizlere dinamik bir linq sorgusu nasıl geliştirilir izah etmeye çalışacağım.

LinqPad adresinden gerekli setup işlemlerini yapıyor ve LinqPad'i açıyorsunuz

 

- Öncelikli olarak Sol menüdeki Add Connection bölümünü tıklayarak connection oluşturmanız gerekmektedir.Default linki kullanarak devam et diyerek connection kurabilirsiniz. (Güncelleme 25.04.2016 )Connection oluştururken "Pluralize" seçeneğinin açık olup olmadığını dikkat edin. Ben kapalı olarak kullandığım için bir müddet neden Expandable komutum çalışmadı diye zaman harcadım. Meğerse tablo adının sonuna "s" eklemiş

 

- Şimdi sıra geldi dinamik parametreler eklememize yardımcı olan LinqKit dll'ini yüklemeye. Bu dll'i nuget yada What is LINQKit? makalesinin altındaki download linki ile yükleyebilirsiniz. 

-  LinqKit kurduğunuz yerden LinqPad'a refernce olarak eklemeniz gerekmektedir. Bunun için F4 Tuşuna basmalısınız. Karşınıza Add Reference penceresi çıkacak. Browse seçilerek LinqKit işaret edildikten sonra, Additional Namespace inmport bölümünden LinqKit adı yazılarak LinqPad'in artık LinqKit'i tanıması sağlanır.

 

- Daha sonra Language seçmelerinden c# statements seçmelisiniz.

 

Ben kendi örneğimde FSYS_USERS tabloma OnlyActive User parametresini test ettim. Siz kendi tablolarınızı çağırarak test yapabilirsiniz. Bu arada Context adı yazmadan direk olarak tablo adı yazdığıma dikkat edin.

var OnlyActiveUsers = true;
Expression<Func<FSYS_USERS, bool>> FSYS_USERSPredicate = p1 => true;

            if (OnlyActiveUsers)
            {
                FSYS_USERSPredicate = FSYS_USERSPredicate.And(z => z.FSTATUS == 'A');
            }
			
var x = from c in FSYS_USERS.Where(c => true).Where(FSYS_USERSPredicate).OrderBy(o=> o.ADSOYAD)
                    select c;

 //           x.ToList();
 
 x.Dump();

 

Yukarıdaki örnekte Eğer OnlyActiveUsers set edilirse linq cumlesine bir predicate daha ekleniyor. Run tuşuna basarak aşağıdaki tablardan dönüş değerlerini, sonuçta oluşan dinamik linq cümlesini ve sql'e giden cümleyi görebilirsiniz. Dump Komutu LinqPad'in aşağıda listeyi görebilmenizi sağlayan bir Extension komutu. ToList'ini alıp aşağıda sonuç tabloayu görmenizi sağlıyor.

Burada gerekli testleri yaptıktan sonra artık sonuç fonksyonumuzu oluşturabiliriz.

public IEnumerable<FSYS_USERS> GetActiveUsersShortInfo(bool OnlyActiveUsers)
        {
            //var FSYS_USERSPredicate = PredicateBuilder.True<FSYS_USERS>();

            //if (OnlyActiveUsers)
            //{
            //    FSYS_USERSPredicate.And(z => z.FSTATUS == "A");
            //}

            //var x = from c in MasterContext.FSYS_USERS.AsExpandable().Where(FSYS_USERSPredicate.Compile())
            //        select c;

            Expression<Func<FSYS_USERS, bool>> FSYS_USERSPredicate = p1 => true;

            if (OnlyActiveUsers)
            {
                FSYS_USERSPredicate = FSYS_USERSPredicate.And(z => z.FSTATUS == "A");
            }

            var x = from c in MasterContext.FSYS_USERS.AsExpandable().Where(c => true).Where(FSYS_USERSPredicate.Compile()).OrderBy(o=> o.ADSOYAD)
                    select c;

            return x.ToList();
        }

 

Bu şekilde tam olarak dinamik bir parametreyi Entity Framework yapımıza eklemiş olduk. Method daki AsExpandable ve Compile komutları LinqKit aracılığı ile gelen extension komutlar.

(Güncelleme 25.04.2016) Eğer c# statement linq cümlesinde bir class yada method kullanmak isterseniz. Bunuda düşünmüşler :) tek yapmanız gereken statement sonunda "}" ile linq bölümünü eklemek ve ardına istediğiniz kadar method ve class ekleyebilirsiniz. Writing Methods and Classes in LINQPad Burada detaylı bir şekilde anlatıyor. Denedim çok güzel çalışıyor.

 

İyi çalışmalar.



Sql Text Formatlama

clock Haziran 26, 2015 11:40 by author OzgurOzvaris

Merhaba,

Bazen sql'e gönderdiğiniz dinamik sorgular uç uca eklenince çirkin bir görüntü oluşturabilir.

Bu durumda 

http://www.dpriver.com/pp/sqlformat.htm

sitesini bir denemenizi tavsiye ederim.

 

İyi çalışmalar.



Entity Framework Join

clock Eylül 3, 2014 12:37 by author OzgurOzvaris

Merhaba Arkadaşlar,

Kaynak,

Entity Framework Query for inner join

Entity Framework Join 3 Tables

Entity Framework LINQ joining 5 tables on multiple columns (impossible?!)

Joining tables using more than one column in Linq To Entities

The type arguments cannot be inferred from the query...

Bazen database tarafında tablolar birbiri ile ilişkili olmadığında yada daha esnek conditionlar eklemek istediğinizde (ilişkili ve derinlerdeki tablolara condition eklemek istediğiniz durumlar gibi) EF'ün "Join" komutuna ihiyaç duyabilir siniz.

 Güzel bir örnek olmasından dolayı kaynaklar'dan birinde geçen örneği paylaşıyorum.

from s in db.Services
join sa in db.ServiceAssignments on s.Id equals sa.ServiceId
where sa.LocationId == 1
select s

Eğer birden fazla kolon joinlemek isterseniz...

var match = from t1 in context.cKNA1
             join t2 in context.cKNB1 on 
                    new { t1.KUNNR, t1.RowId } equals 
                    new { t2.KUNNR, t2.RowId }
             join t3 in context.cKNVV on 
                    new { t2.KUNNR, t2.RowId } equals 
                    new { t3.KUNNR, t3.RowId }
             join t4 in context.cKNVH on 
                    new { t3.KUNNR, t3.RowId } equals 
                    new { t4.KUNNR, t4.RowId }
    SELECT t1.KUNNR;


Yada ikinci bir syntax olarak...

from a in Table1s 
from b in Table2s
where a.ID1Table1 == b.ID1Table2 && a.ID2Table1 == b.ID2Table2
select new {a.ID1Table1, a.ID2Table1, a.Value1Table1, b.ID3Table2, b.Value1Table2}


Eğer yapılan join işlemlerinde field isimleri birbirini eşit değilse "The type arguments cannot be inferred from the query..." alabilirsiniz. Böyle bir durumda "new" komutu ile oluşturduğunuz class alanlarına ortak isimler vermelisiniz.

join inventory in Models.Inventories on new
{
	Supplier = equivalency.EquivalencySupplier,
	Part = equivalency.EquivalencyPart
} equals new
{
	Supplier = inventory.Supplier,
	Part = inventory.Part
}

 

İyi çalışmalar.



Entity Framework'e Giriş

clock Eylül 3, 2014 11:47 by author OzgurOzvaris

Merhaba Arkadaşlar,

Entity Framework (EF) ile ilgili pek yazı kaleme almadım. Aslında bu tarafta hatırı sayılır miktarda Entitiy Framework tecrübesi birikti. Sizlerle ara ara bunlarıda paylaşmaya çalşacağım. Aslında bu yazıda "Entity Framework Join" konusuna deyinecektim ancak bu vesile ile biraz Entity Frame work'un genel konularına değineyim.

Entity Framework emsalleri ile karşılaştırılınca gerçekten bambaşka bir dünya. Bazen insanı çılgına çevirecek kadar zor, bazende ya bunuda mı yapıyor helal olsun bu adamlara diyecek kadar tatminkar. Bazende bunu nasıl hâlâ eklememişler diyecek kadar sizi üzen, sürekli size karma karışık duygular yaşatan, sürekli gelişen bir sistem. Zaten 6.0 versiyonunu görmesi ve hala hızla gelişmeside buna en basit örnek.

Ayrıca hâlâ güçlü bir yazılımının data katmanı EF ile geliştirilebilir mi diye piyasada ciddi endişeler var. Kabul elmek gerek ki "SQL" database ile kurulan çok ciddi bir iletişim yöntemi ve belkide EF hiçbir zaman onun kadar güçlü olamayacak. Ancak sql ve EF'ü kıyaslamak bana adil gelmiyor. EF gücünü sistemlerinden (Code First, Design First, Database First, POCO vb. ) alıyor. EF adeta kıyas edersek yazı dünyasındaki Word uygulaması yolun da gidiyor, sql ise database dünyasının karakalemi gibi. Sql'de varyasyonlar bir hayli çoğalmış durumda tabi ki EF'de varyasyonlar o kadar çok değil.

Entitiy Framework'te doğru synax ve doğru sql çıktısı çok önemli. Gerçekten çok güçlü bir yapı. Ancak sadece yazdım bitti diyemiyorsunuz. Bir şekilde alışana kadar sql profiler'dan ve ya başka şekillerde EF'ün efektif SQL cümleleri üretip üretmediğini kontrol etmeniz gerekiyor.

Aslında bu makaleye "Entity Framework Join" demiştim ancak yazı başka yöne doğru gidince başlığı şimdiki başığa çevirdim.

Birazdan "Entity Framework Join" makalemide yayınlayacağım inşallah.

Herkese iyi çalışmalalar.



Sql Server free profiler

clock Eylül 3, 2014 11:12 by author OzgurOzvaris

Merhaba Arkadaşlar,

sql le uğraşan herkesin arada bir gönlünden geçmiştir. Acaba free bir query tool'y varmıdır, free bir profiler tool'u varmıdır diye.

Daha önce free query tool'unu paylaşmıştım.

Simple sql server management studio alternatifleri

Bu gün ise free bir profiler paylaşıyorum

ExpressProfiler

Umarım faydalı olurlar.

İyi çalışmalar.

 



Simple sql server management studio alternatifleri

clock Haziran 30, 2014 10:25 by author OzgurOzvaris

Merhaba,

Kaynak : http://stackoverflow.com/questions/5170/sql-server-management-studio-alternatives-to-browse-edit-tables-and-run-queries

Arkadaşlar bazen uygulama sunucunuzda sql server management studio olmayabilir. Bildiğiniz üzere bu tool free bir tool ancak indirmesi kurması zaman alıyor. Eğer acil olarak bir sunucuda sql bağlantısını test etmeniz gerekirse sizlere uzun zamandır böyle zamanlarda kullandığım Query Express isimli tool'u tavsiye ederim.

Buradan download edebiilirsiniz Query Express .

İyi çalışmalar.

 



Sqllite MSSQL bağlantısı

clock Haziran 26, 2014 16:03 by author OzgurOzvaris

Değerli Arkadaşlar,

Kaynak :

Creating a SQL Server Linked Server to SQLite to Import Data

SQLlite'ı hafife almamanızı tavsiye ederim. Adı lite olsada çok iş görüyor. Loglama sistemimiz tamamen ona emane etmiş durumdayız. Çok basit bir log tablosuna sürekli olarak log satırları yazdırıyoruz yaklaşık olarak günde 300.000 satırdan fazla log satırı yazıldığı oluyor. Ama hiç bir veri kaybımız olmadı. Sorunları yok değil ama loglama konusunda beklentimizi karşıladığını söylemelim.

İyi güzel logluyoruzda bu logları nasıl işleyeceğiz ve analiz edeceğiz. İşte burada lite olmasının sorunları başlıyor. Excel'e çıktı alması bizi 65bin küsür sınırı ile muhatap ediyor excel export adı altında yeni satır sınırı olmayan excellere export yapsada bu işlemi hem çok yavaş hemde açık olan excel'e satır satır eklemek gibi garip bir yöntem kullandığı için 100bin üzeri satırlada ciddi zaman kaybı oluyor. Asıl sorun bu değil asıl sorun sunucumuzda bu yöntemle açabileceği bir excel yüklü olmaması. Bu durumda iş parçalı olarak küçük excel'lere atılarak yapıloyor sonra bu exceller analiz için başka satır sınırı olmayan excelde birleştiriliyor bayağı uzun bir angarya.

Bu gün bir den bir ampul yandı kafamda. Ya dedim bu sql lite mssql ile bir bağlantı kuramazmı. Hemen karşıma olabileceğine dair linkler geldi. Bu linkteki adımları tek tek anlatmayacağım. Böyle böyle bir şeye ihtiyaç duyarsanız sizde bu adımları uygulayabilirsiniz.

http://www.mssqltips.com/sqlservertip/3087/creating-a-sql-server-linked-server-to-sqlite-to-import-data/

Öncelikle bir odbc driver kurmanız gerekiyor

http://www.ch-werner.de/sqliteodbc/

Sonra bu odbc driver'a konuda bahsedildiği gibi SystemDSN altına Add işlemiş kurduğunuz SQLLite 3 driver'ını kullanarak database'iniz bağlıyorsunuz.

Ardından sql server'a linked server olarak tanımlıyorsunuz.

USE [master]
GO
EXEC sp_addlinkedserver 
   @server = 'Mobile_Phone_DB_64', -- the name you give the server in SSMS 
   @srvproduct = '', -- Can be blank but not NULL
   @provider = 'MSDASQL', 
   @datasrc = 'Mobile_Phone_DB_64' -- the name of the system dsn connection you created
GO

Daha sonra sorgulamaya başlıyorsunuz :)

Select *
from openquery(Mobile_Phone_DB_64 , 'select * from db_notes')
GO

Select * into SQLite_Data -- This creates a table
from openquery(Mobile_Phone_DB_64 , 'select * from db_notes')
GO

Bu kadar basit.

İyi çalışmalar.



MSSQL Multi core kullanımı

clock Haziran 11, 2014 13:02 by author OzgurOzvaris

Değerli arkdaşlar ,

Microsoft SQL ile ilgili önemli sorunlarda bir taneside multicore'a karşılık performans artışı sorusu. Bu soru dipsiz bir kuyu gibi. En azından cpu lara tam erişebiliyormuyuz derseniz şu sorguyu kullanabilirsiniz.

Kaynak :

How many CPU cores can SQL Server use?

SQL SERVER – Measure CPU Pressure – CPU Business

Sql kaç cpu görüyor

select cpu_count from sys.dm_os_sys_info

Bu cpu lardan kaçı aktif durumda

select scheduler_id,cpu_id, status, is_online from sys.dm_os_schedulers where status='VISIBLE ONLINE'

Bu cpu'lar üzerindeki iş yükü nedir

SELECT
scheduler_id,
cpu_id,
current_tasks_count,
runnable_tasks_count,
current_workers_count,
active_workers_count,
work_queue_count,
pending_disk_io_count
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255;

İyi çalışmlalar.



Plan Caching in SQL Server 2008, Forcing Query Plans

clock Haziran 4, 2014 11:05 by author OzgurOzvaris

Değerli Arkadaşlar,

Bu aralar sql performansı ile uğraştığımdan bahsetmiştim.

"Çok sayıda çalışan bir sorgunuz varsa herşey sorundur demektir."  Özgür Özvarış :) 04/06/2014

Kaynak

Plan Caching in SQL Server 2008

Forcing Query Plans

How to determine what is compiling in SQL Server

Amacımız çok çalışan sorgumuzun herseferinde çalışma planın derlenmesini engellemek. Şimdi birilerinin stored procedur yapın dediğini duyar gibiyim :) Ama bu sorgumuz o kadar zorlu bir sorguki araya giren where conditionları stored procedure dahi olsa yapıyı bozuyor.

Süreç uzun çalışan sorgularımda çok uzun compile süreleri görmemle başladı. Daha sonra How to determin what is compilin in SQL Server makalesinde söylendiği üzere profiler kriterlerme Perfomance aldınaki fieldları eklediğimde gerçekten her sorgumun ciddi manada derlendiğini gördüm. Şimdi sıra derlenmesi engellemek Plan Caching makalesinde geçen derlemelerin caclenmesi ve reuse edilmesi mevzuna geldi. Ancak sorgumuzu parametrik yamaktansa çok çalışan iki case için exceution planı force etmek daha çok işimizde geldi. Bizde Forcing Query Planda söylenen yöntem ile bu iki sorgu case'imizi force etmeye karar verdik.

Olurda force etmek isterseniz Quary Analizerdan excecution planla sorgunuzu çalıştırın. Save As XML deyin. direk makaledeki gibi eklemeyin içindeki iki yeri düzelmeniz gerekiyor Öncelikle ' karakterlerinin '' (iki tek tırnak yanyana) replace işlemini yapın. Ardından "StmtSimple" nodundaki "StatementText" Fieldını temizleyin şimdi sorunsuz eklenecektir.

İyi çalışmalar.

 

 



Hakkımızda  AboneOl 

Blog Yayınımıza Hoşgeldiniz.

Month List

RecentPosts

Sign In