Join | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar join

C# 1 vs C# 6

21 November 2015 Yorum yapılmamış

Eğitim vermeye ilk başladığım yıllarda Console Application projeleri üzerinden uygulamaların aldığı parametreleri ve bu parametreleri nasıl kullanabileceğimizi anlatıyordum.

En basit diyebileceğimiz bu tip işlerin bile yazılım dünyasında ne kadar değiştiğini geçenlerde konuştuğum ve o zamanlar benim eğitimimi dinleyen bir tanıdığım ile tartıştık.

Aklıma hemen bir test projesi açmak ve kendi gözlerimle görmek geldi.

İlk olarak eski usül yöntemler ile Console Application projesinde parametreleri alalım;

Şimdi yeni usül yöntemler ile Console Application projesinde parametreleri alalım;

Ne dersiniz, C# yazılım geliştiriciler olarak işlerimiz kolaylaştı mı?

Windows Phone 8 için Radyo Frekansları uygulaması

19 December 2012 Yorum yapılmamış

Windows Phone 8 için şehir-şehir radyo frekanslarını görebileceğimiz bir uygulama geliştireceğiz.

Bu uygulamanın geliştirilmesi sırasında Pivot, PivotItem, LongListSelector, DataTemplate, WebClient gibi sınıfları kullandığımız kodlar yazacağız.

Öncelikle RadyoListe isimli yeni bir Windows Phone App projesi oluşturalım;

Windows Phone App Project

Proje oluşturduktan sonra gelen Windows Phone Platform versiyon seçim penceresinde Windows Phone OS 8.0 seçeneğinin seçili olduğundan emin olmalıyız;

Windows Phone 8.0 SDK

Uygulama ihtiyaç duyduğu veriyi internetten indireceği için WMAppManifest.xml dosyasında Network erişim izninin istenmiş olması gerekiyor;

<Capabilities>
	<Capability Name="ID_CAP_NETWORKING" />
</Capabilities>

Radyo listesi için json formatında hazırladığım veriyi kendi sunucuma radyolar.json ismi ile yükledim.

Json formatında okuyacağımız bu veriyi işlemek için References içerisine Newtonsoft Json.Net (4.5.11) Nuget paketini eklemeliyiz;

Newtonsoft Json.Net Nuget Package

Models isminde bir dizin ekleyip, içerisinde LiveData, City, Channel, Frequency isimli sınıflar oluşturalım;

LiveData.cs

public class LiveData
{
	public IEnumerable<City> Cities { get; private set; }

	public IEnumerable<Channel> Channels { get; private set; }

	public IEnumerable<Frequency> Frequencies { get; private set; }

	public LiveData()
	{
		this.Cities = new List<City>();
		this.Channels = new List<Channel>();
		this.Frequencies = new List<Frequency>();
	}

	public LiveData(string LiveDataResponse)
	{
		var LiveDataResult = JsonConvert.DeserializeObject<LiveData>(LiveDataResponse);

		this.Cities = LiveDataResult.Cities;
		this.Channels = LiveDataResult.Channels;
		this.Frequencies = LiveDataResult.Frequencies;
	}
}

City.cs

public class City
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Channel.cs

public class Channel
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Frequency.cs

public class Frequency
{
	public int CityID { get; set; }

	public int ChannelID { get; set; }

	public float No { get; set; }
}

Uygulama ilk açıldığında çalıştırılan App (App.xaml.cs) sınıfına aşağıdaki kodları ekleyelim;

public static Action DataLoaded;

public static LiveData ViewModel = null;

public async static void LoadData()
{
	WebClient wc = new WebClient();

	wc.DownloadStringCompleted += (s, e) =>
	{
		if (e.Error == null)
		{
			ViewModel = new LiveData(e.Result);

			if (DataLoaded != null)
			{
				DataLoaded();
			}
		}
	};

	wc.DownloadStringAsync(new Uri("http://www.enginpolat.com/application-data/radyolar.json"));
}

App sınıfının constructor’ında LoadData() method’unu çağıralım;

LoadData();

Kodları inceleyecek olursak;

Sınıf seviyesinde tanımlanan LiveData tipindeki ViewModel değişkeni, LoadData() method’u içerisinde asenkron olarak doldurulur. ViewModel değişkenine değer ataması yapıldıktan sonra DataLoaded action‘ını dinleyen bir method varsa tetiklenir.

Bu sayede uygulamanın açılışı esnasında internetten verinin indirilmesi ve deserialize edilmesi asenkron olarak yapılmış olur.

MainPage.xaml dosyasında ekranda sadece bir Pivot kontrolünün gösterilmesini sağlayalım;

<Grid x:Name="LayoutRoot" Background="Transparent">
	<Grid.RowDefinitions>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<phone:Pivot Margin="0,10,10,10" Title="Radyo Listesi" Name="pvtSehirListesi" Grid.RowSpan="1" />
</Grid>

Artık MainPage.xaml.cs dosyasındaki constructor‘a giderek ekranı dolduracak kodları yazabiliriz;

App.DataLoaded = () =>
{
	foreach (City Sehir in App.ViewModel.Cities)
	{
		PivotItem pi = new PivotItem();
		pi.Header = Sehir.Name;

		LongListSelector list = new LongListSelector();
		list.ItemTemplate = Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;
		list.ItemsSource = (from Frekans in App.ViewModel.Frequencies
			join Kanal in App.ViewModel.Channels on Frekans.ChannelID equals Kanal.ID
			where Frekans.CityID == Sehir.ID
			select new { ChannelName = Kanal.Name, Frequency = Frekans.No.ToString("00.0") }).ToList();

		pi.Content = list;

		pvtSehirListesi.Items.Add(pi);
	}
};

Böylece App sınıfında, ViewModel değişkenine değer yükledikten sonra tetiklediğimiz Action içerisinde bir foreach döngüsü çağırmış oluyoruz.

Döngü içerisinde ilk önce yeni bir PivotItem tipinde değişken oluşturuyoruz ve Header özelliğine döngü değişkeninden elde ettiğimiz şehir ismi bilgisini atıyoruz.

PivotItem tipindeki değişkenin Content özelliğine, LongListSelector tipinde yeni bir değişken atıyoruz.

LongListSelector tipindeki değişkenin ItemsSource özelliğine App.ViewModel değişkenindeki değerlerden LINQ Expression ile oluşturduğumuz listeyi atıyoruz.

Aynı şekilde LongListSelector tipindeki değişkenin ItemTemplate özelliğine

Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;

değerini atıyoruz.

Son olarak, App.xaml dosyasına FrequencyListItemTemplate ismindeki Resource‘u ekliyoruz;

<Application.Resources>
	<DataTemplate x:Name="FrequencyListItemTemplate">
		<StackPanel Margin="0,0,0,17">
			<TextBlock Text="{Binding ChannelName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
			<TextBlock Text="{Binding Frequency}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
		</StackPanel>
	</DataTemplate>
</Application.Resources>

Uygulamayı çalıştırdığımızda aşağıdaki ekran görüntüsünü görüyor olmamız lazım;

Radyo Liste Windows Phone 8 Application

Projenin kodlarını buradan indirebilirsiniz.

StringBuilder alternatifi olarak String.Join

07 February 2012 Yorum yapılmamış

String sınıfının immutable olduğunu duymayanımız kalmamıştır (bknz; string sınıfı neden immutable?)

string tipindeki bir değişkenin değeri üzerinde sürekli değişiklik yapıp Garbage Collector‘a gereksiz iş oluşturmak yerine, StringBuilder sınıfını kullanırız (Garbage Collector hakkında detaylı bilgi için bknz; Garbage Collector Temelleri ve Performans Noktaları)

Çeşitli sebeplerden dolayı (Loglama, XML veya JSON veri üretme, vs) sınıflarımızın ToString() method’larını override ederiz (bknz; ToString() Method’unu override etmek)

ToString() method’undan geriye string değer döndüreceğimiz için method içerisinde string değer tutabilecek bir değişkene ihtiyaç duyarız. Bu değişken yukarıda bahsettiğimiz nedenlerden dolayı genelde StringBuilder tipinde olur.

Örnek ProductOrderCollection sınıfımızın ProductID ve Orders isminde property‘leri olduğunu varsayalım;

public class ProductOrderCollection
{
	public int ProductID { get; set; }

	public IEnumerable<Order> Orders{ get; set; }
}

ToString() method’unu override ettiğimiz örnek kod parçası;

public override string ToString()
{
	StringBuilder sb = new StringBuilder();
	sb.Append("Product{Id=");
	sb.Append(this.Id);
	sb.Append(",Orders=");
	if (this.Orders == null)
	{
		sb.Append("null");
	}
	else
	{
		sb.Append("[");
		for (int i = 0; i < this.Orders.Length; i++)
		{
			if (i > 0 && i < this.Orders.Length - 1)
			{
				sb.Append(",");
			}

			sb.Append(this.Orders[i]);
		}

		sb.Append("]");
	}

	sb.Append("}");

	return sb.ToString();
}

Yukarıdaki örnek kod sayesinde ProductOrderCollection sınıfının verilerinden JSON değer üretebiliriz.

StringBuilder sınıfı yerine String.Join methodunu kullanarak yapacak olsaydık;

public override string ToString()
{
	StringBuilder sb = new StringBuilder();
	sb.Append("Product{Id=");
	sb.Append(this.Id);
	sb.Append(",Orders=");
	if (this.Orders == null)
	{
		sb.Append("null");
	}
	else
	{
		sb.Append("[");
		sb.Append(string.Join(",", this.Orders));
		sb.Append("]");
	}

	sb.Append("}");

	return sb.ToString();
}

Hatta if/else kod parçasını daha da kısaltabiliriz;

public override string ToString()
{
	StringBuilder sb = new StringBuilder();
	sb.Append("Product{Id=");
	sb.Append(this.Id);
	sb.Append(",Orders=");
	sb.Append(this.Orders == null ? "null" : "[" + string.Join(",", this.Orders) + "]");
	sb.Append("}");

	return sb.ToString();
}

StringBuilder sınıfını hiç kullanmamak için;

public override string ToString()
{
	return string.Join("Product{Id=", this.Id, ",Orders=", this.Orders == null ? "null" : "[" + string.Join(",", this.Orders) + "]", "}");
}

Sql Server Identity Sutunları Belirlemek

20 January 2011 Yorum yapılmamış

BilgeAdam’daki eski öğrencilerimden biri şu soruyu sordu; “Herhangi bir veritabanındaki tüm tablolarda bulunan Identity Sütunları belirlemenin bir yolu var mıdır?”

Aslında bir değil, tam üç yolu var;

Yöntem 1 : COLUMNPROPERTY fonksiyonunu kullanmak

SELECT
	TABLE_NAME,
	COLUMN_NAME
FROM
	INFORMATION_SCHEMA.COLUMNS
WHERE
	COLUMNPROPERTY(OBJECT_ID(TABLE_NAME), COLUMN_NAME, 'ISIDENTITY') = 1
ORDER BY
	TABLE_NAME

Yöntem 2 : SYS.ALL_COLUMNS View’unu kullanmak

SELECT
	OBJECT_NAME(AC.OBJECT_ID),
	SO.NAME
FROM
	SYS.ALL_COLUMNS AS AC
	INNER JOIN SYS.OBJECTS AS SO ON OBJECT_NAME(AC.OBJECT_ID) = SO.NAME
WHERE
	AC.IS_IDENTITY = 1 AND
	SO.TYPE = 'U'

Aynı yöntemi biraz faklı olarak şöyle de yazabiliriz;

SELECT
	OBJECT_NAME(OBJECT_ID),
	NAME
FROM
	SYS.ALL_COLUMNS
WHERE
	IS_IDENTITY = 1 AND
	OBJECTPROPERTY(OBJECT_ID, 'ISUSERTABLE') = 1

Yöntem 3 : SYS.IDENTITY_COLUMNS View’unu kullanmak

SELECT
	OBJECT_NAME(IC.OBJECT_ID),
	SO.NAME
FROM
	sys.identity_columns AS IC
	INNER JOIN SYS.OBJECTS AS SO ON OBJECT_NAME(IC.OBJECT_ID) = SO.NAME
WHERE
	SO.TYPE = 'U'

Aynı yöntemi biraz faklı olarak şöyle de yazabiliriz;

SELECT
	OBJECT_NAME(OBJECT_ID),
	NAME
FROM
	sys.identity_columns
WHERE
	OBJECTPROPERTY(OBJECT_ID, 'ISUSERTABLE') = 1

Bu kodda ne yanlış var? – 6

03 September 2010 5 yorum

Bir kitabevi için web uygulaması geliştiriyorsunuz. Yaptığınız analize dayanarak, uygulamanın veritabanını aşağıdaki gibi tasarladınız;

Bu kodda ne yanlış var? - 6 / Veritabanı Modeli

Veritabanı modelinize göre, her kitabın sıfır veya daha fazla yazarı olabilir, her yazarın sıfır veya daha fazla kitabı olabilir.

Toplam Kitap Adedi ve Toplam Yazar Adedi sorularına cevap verebilmek için, aşağıdaki sorguyu yazdınız;

SELECT DISTINCT
	COUNT(Yazarlar.YazarID) AS ToplamYazarAdedi,
	COUNT(Kitaplar.KitapID) AS ToplamKitapAdedi
FROM
	Yazarlar
	FULL JOIN YazarKitaplari YK ON Yazarlar.YazarID = YK.YazarID
	FULL JOIN Kitaplar ON YK.KitapID = Kitaplar.KitapID

Problem, rakamların beklediğinizden yüksek çıkması.

Sizce problem nedir ve nasıl düzeltebiliriz?