ASP.NET MVC’de Bir View İçinde Birden Çok Model Kullanımı

View’ler içinde model kullanmak istediğimizde bir modele bağlı kalmak istemediğimiz durumlar olabilir. Örneğin aşağıdaki gibi bir tanımlama yaparsak View, en son tanımlanan Model’i geçerli sayar.

@model StuPerformance.Models.Exam
@model StuPerformance.Models.Student

 

Bunun yerine kullanmak istenen Model’lerin bir araya toplandığı bir üst sınıf olarak düşünülebilecek Model sınıfı kullanabiliriz.

Örneğin Class ve Lecture adında iki modelimiz olsun. Buradaki verileri iki adet DropDownList aracılığıyla View içerisinde göstermeye çalışalım. İlk olarak Models klasörümüze bu iki modeli içeren ayrı bir class oluşturuyoruz.

namespace StuPerformance.Models
{
    public partial class ModelLists
    {
        public Class ClassM { get; set; }
        public Lecture LectureM { get; set; }
    }
}

 

ModelLists adını verdiğimiz bu modeli ilgili view içinde tanımlayarak hem Class, hem Lecture modellerini kullanabiliriz.

@model StuPerformance.Models.ModelLists

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
<div class="form-group">
    @Html.LabelFor(model => model.StudentExamM, "Class", new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("ClassId", String.Empty)
        @Html.ValidationMessageFor(model => model.ClassM.ClassId)
    </div>
    </div>
<div class="form-group">
    @Html.LabelFor(model => model.StudentExamM, "Lecture", new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("LectureID", String.Empty)
        @Html.ValidationMessageFor(model => model.LectureM.LectureID)
    </div>
</div>
} 

 

Burada ilk DropDownList için model.ClassM.ClassId, diğer DropDownList için model.LectureM.LectureID kullanılmıştır.

ASP.NET MVC’de Mevcut Veritabanından Code First İle Model Oluşturma

Son yıllarda sık kullanılan Code First ile modelleme, var olan bir veritabanını esas alarak tersine mühendislik yoluyla yapılabiliyor. Aslında bu seçenek, Entity Framework 6.1.1 ile gelen bir özellik. O yüzden ilk olarak buradan Entity Framework 6.1.1 sürümünü indirip kuruyoruz. Örneğin anlaşılabilir olması için veritabanını oldukça basit seçtim.

1Projemize sağ tıklayıp Add->New Item->ADO.NET Entity Data Model seçiyoruz. Modelimize bir isim verdikten sonra karşımıza aşağıdaki gibi bir seçenek çıkıyor. Burada Code First From Database seçeneğini işaretliyoruz.

2Daha sonra önceden oluşturulmuş veritabanımızı belirterek connectionString ve ayarlamaların yapılmasını sağlıyoruz.

3Oluşturulan Haber.cs, Kategori.cs ve HaberContext.cs modellerini görebiliriz.

[Table("Haber")]
    public partial class Haber
    {
        public int Id { get; set; }

        [Required]
        [StringLength(50)]
        public string HaberAd { get; set; }

        [Column(TypeName = "ntext")]
        public string HaberMetin { get; set; }

        public int? KategoriId { get; set; }

        public virtual Kategori Kategori { get; set; }
    }

[Table("Kategori")]
    public partial class Kategori
    {
        public Kategori()
        {
            Haber = new HashSet<Haber>();
        }

        public int Id { get; set; }

        [StringLength(50)]
        public string KategoriAd { get; set; }

        public virtual ICollection<Haber> Haber { get; set; }
    }

public partial class HaberContext : DbContext
    {
        public HaberContext()
            : base("name=HaberContext")
        {
        }

        public virtual DbSet<Haber> Haber { get; set; }
        public virtual DbSet<Kategori> Kategori { get; set; }
        public virtual DbSet<sysdiagrams> sysdiagrams { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Haber>()
                .Property(e => e.HaberAd)
                .IsUnicode(false);

            modelBuilder.Entity<Kategori>()
                .Property(e => e.KategoriAd)
                .IsUnicode(false);
        }
    }

Web.config içinde Context adının kullanıldığı bağlantı ayarı da aşağıdaki gibi otomatik olarak oluşturulmaktadır.

<connectionStrings><add name="HaberContext" connectionString="data source=nevra-nevra\sqlexpress;initial catalog=Haber;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" /></connectionStrings></configuration>

C# : Metin İçinde Metin Arama – 2

İlk yazıda kullandığımız IndexOf metodu yerine aynı sorunu LINQ sorguları ile çözmeye çalışacağız. Öncelikle LINQ mimarisine bakarsak, üzerinde çalıştığımız çeşitli arayüzler içeren veri kümelerinde ve veri kaynaklarında(XML, JSON vs.) sorgulama yapmamızı sağlayan ifadelerdir. Aslında LINQ yapısı programlama diline, sorgulama becerisi ekler, sorgulama ve sonuç kümesi döndürme gibi işlemleri ise sağlayıcı(provider) dediğimiz yapılar gerçekleştirir. Bu sorun için LINQ yapısının veri kümeleri üzerinde sorgulama yapmamıza imkan veren ifadeler olduğunu bilmemiz yeterli. Yazıda bir metin içinde aranan kelimeyi LINQ to Objects sağlayıcısının bize sunduğu Count metodunu kullanarak bulmaya çalışacağız.

 string metin, aranan;
 char[] noktalama= { ',', '!', '#', '$', '%', '&', '(', ')', '*', '+', '-', /*'.',*/ '/', ':', ';', '<', '=', '>', '?', '@', '[', '/', ']', '^', '{', '|', '}', ' ' };
 Console.WriteLine("Metni giriniz: ");
 metin = Console.ReadLine().ToString();
 Console.WriteLine("Aranan kelimeyi giriniz: ");
 aranan = Console.ReadLine().ToString();
 string[] kelimeler = metin.Split(noktalama);
 int adet = kelimeler.Count(kelime => kelime == aranan);
 Console.WriteLine(aranan + " kelimesi " + adet + " adet bulunmustur.");
 Console.ReadLine();

C#: PadLeft ve PadRight Metotları

C# dilinin string sınıfı için sağladığı çok sayıda yararlı özellik bulunuyor, Pad metodu da karakter sayısının önemli olduğu işlemlerde kullanılan pratik bir metot.

PadLeft ve PadRight metotlarını kısaca açıklarsak string ifadelerimizin karakter sayısı ne olursa olsun belli bir karakter sayısına uymasını istiyorsak o sayıya tamamlamasını sağlıyor. Bir örnek olarak decimal sayıları binary olarak çevirdiğimizde soldaki 0 değerlerini göremeyiz, ancak uygulamada göstermek istiyorsak PadLeft metotundan yardım alabiliriz.

for (int i = 0; i < 16; i++)
  {
     dizi[i] = Convert.ToString(i, 2);
     dizi[i] = dizi[i].PadLeft(4, '0');
  }

Burada 0-15 arasındaki sayıları binary hale getiriyoruz ancak PadLeft metotunu kullanmasaydık örneğin 2 sayısı ’10’ olarak görülecekti. Biz string ifadenin değerine bakmaksızın 4 karakter halinde kaydetmiş olduk.

Metodun ilginç bir özelliği de aritmetik işlemlerde kullandığınızda yeni bir sayı olarak kabul etmesi. Ancak bu durum, metotların string bir ifadeyi değiştirmediğini, sadece istenen karakter sayısına tamamladığını unutmamak gerek.

string deger = "3";
int sonuc = Convert.ToInt32(deger.PadRight(2, '0')) - 1;
Console.Write(sonuc); // 29 yazdırır.
Console.Read();

Eğer string ifadenin soluna ya da sağına herhangi bir karakter yerine boşlukla doldurmak istiyorsak metoda sadece istenen karakter sayısını vermek yeterli oluyor.

string str = "'Solda 10 bosluk olacak'";
Console.Write("Pad Kullanımı");
Console.WriteLine(str.PadLeft(32));
Console.Read();

str değişkenimiz 22 karakterden oluştuğundan soldan 10 karakter boşluk bırakmak için PadLeft metoduna 32 değerini vermiş olduk. PadRight metodu da sağdan karakter doldurmak için PadLeft ile aynı mantıkta kullanılabilir.

SQL Sorgusunu Sayısal Değer Olarak Kullanma

Otomatik hesaplama yapan ya da sütunlar arasında aritmetik işlemler gerektiren bir uygulama üzerinde çalışıyorsanız bir SQL sorgusundan dönen değeri sayısal olarak ifade etmeniz gerekecektir.

Örnek olarak fiyatı belli olan bir ürünün alış miktarı kullanıcıdan alınsın, her ikisi de tablolarda sütun olarak yer alan alış miktarı ve fiyatı bilgisinin çarpımını elde etmek için ExecuteScalar() metotuna başvurmalıyız. Hatta kullanıcı üründen ne kadar aldığını textBox1’e girdiği anda toplam tutarı textBox2’ye yazdıralım.

  private void textBox1_TextChanged(object sender, EventArgs e)
        {
            SqlConnection baglanti = 
            new SqlConnection("server=.;database=StokTakip;Integrated Security=True");
            baglanti.Open();
            SqlCommand cmd = new SqlCommand("select Fiyati from Urunler 
            where UrunAdi = '" + textBox3.Text + "'",baglanti);
            int fiyat = Convert.ToInt32(cmd.ExecuteScalar());
            int tutar = fiyat * Convert.ToInt32(textBox1.Text);
            try
            {
                textBox2.Text = tutar.ToString();
            }
            catch
            {
                MessageBox.Show("Lutfen sayi giriniz.");
            }
            finally
            {
                textBox1.text = "";
            }
            baglanti.Close();
        }

Kodu kısaca açıklarsak; textBox3 ile aldığımız ürün adının fiyatını getirdik. Kullanıcının textBox2 ile girdiği alış miktarı ile çarpmadan önce fiyatın integer değer çevrilmesi gerekiyor. Bu durumun çözümünde ExecuteScalar() metotu oldukça yararlı.

ExecuteScalar() metotu, veritabanından toplam gibi tek bir değeri döndürmeyi sağlayan hızlı bir araçtır. Döndürdüğü değer, Resultset’in ilk elemanınıdır ve bu elemanın hangi tipte olduğu ilk etapta bilinemeyeceği için nesne(object) olarak kabul edilir. Eğer doğrudan int, string gibi farklı bir türe atamak isterseniz  ‘Cannot implicitly convert type ‘object’ to ‘int’. An explicit conversion exists (are you missing a cast?)’ hatası alırsınız. Bu yüzden gerekli çevirme işlemlerini yapmak gerekir.



			

Algoritma Örnekleri – 1

Problem: 1’den 10’a kadar sayan sayaç ve kullanıcıdan alınan x(sınır değer) değeri ile x+(i*2)^2 kuralı ile tanımlanan s değerlerini hesaplamak ve her biri için asal olup olmadığını kontrol etmek. Bulunan asal sayıların toplamını ve kaç tane olduğunu ekrana yazdırmak.
(Örnek:
x:5, bulunan asal sayı:2 asal sayıların toplamı:190
x:8  bulunan asal sayı:0 asal sayıların toplamı:0)

x2

static void Main(string[] args)
        {
            int i, x, m, s = 0;
            int toplam_asal = 0, sayi_asal = 0;
            Console.WriteLine("Deger giriniz:");
            x = Convert.ToInt32(Console.ReadLine());
            for (i = 1; i <= 10; i++)
            {
                s = x + (i * 2) * (i * 2);
                for (m = 2; m < s; m++)
                {
                    if (s % m == 0)
                    {
                        break;
                    }
                    if(m==s-1)
                    {
                        toplam_asal = toplam_asal + s;
                        sayi_asal = sayi_asal + 1;
                    }
                }

            }
            Console.WriteLine("Deger:" + x + "Bulunan asal sayi: " + sayi_asal + "Toplam:" + toplam_asal);
            Console.ReadLine();
        }
    }

Klavyeden Hangi Tuşa Basıldığını Kontrol Etmek

C’de string ifadelerle çalışılırken genellikle ASCII kodlarına başvurulur. Harfler ya da simgeler yerine klavyede yer alan Home, Insert, Del, Fonksiyon tuşları gibi kısayollar için ise genişletilmiş ASCII kod listesinden yararlanılır.

Burada iki fonksiyondan yararlanılır. Birincisi kbhit() fonksiyonudur. Bir tuşa basıldıysa 1, basılmadıysa 0 değeri döndürür. Döngü içi kontrollerde kullanılabilir. Diğeri olan getch(void) fonksiyonu da herhangi bir karakter alabilir. Alınan tuş kullanılmak istenirse girdi değişkeninde olduğu gibi atama işleminde kullanılabilir.

char girdi;                  
    while (1==1){
          girdi = getch();
		if (kbhit()) { 
                girdi = getch();
				switch (girdi) {

		case 77: 
			printf("Sag ok tusuna bastiniz.\n");	
                        break;

				case 27:
                         printf("Esc tusuna bastiniz.\n");
                         break;

                case 83:
                         printf("Delete tusuna bastiniz.\n");
                         break;

                case 073:
                         printf("F1  tusuna bastiniz.\n");
                         break;

                case 71:
                         printf("Home tusuna bastiniz.\n");
                         break;	

                case 79:
                         printf("End tusuna bastiniz.\n");
                         break;	
				}
		}
    }
	return 0;
}

Diğer kısayol tuşları için genişletilmiş listeye ve tüm listeye buradan ulaşabilirsiniz.