C# 'da database nasıl oluşturulur?

Başlatan Mucit23, 02 Ocak 2017, 16:32:42

Mucit23

Selamlar

Konu başlığında database dedim ama aslında bana tam olarak ne lazım bilmiyorum. İhtiyacım olan şudur. Donanım tarafından C#daki yazılımıma veriler geliyor. Veri sayısının ne kadar olduğu belli değil ama her gelen ver paketinin uzunluğu ve içeriği belli. Paketin  64 adet int değerden oluşuyor. Fakat bu paketlerden kaç adet olduğu bellirli değil.

Ben c# tarafındaki yazılımıma verileri çek dediğim anda bu verileri c# da bir veri tabanına kaydetmem gerekiyor. Tekrar veri al butonuna basarsam ilk önce veri tabanındaki eski verileri silip yerine yeni verileri yazmam gerekiyor.

Şöyle bir tablo oluştursam güzel olur.

1.   125 456 345 765 875 .....  toplam 64 adet değer
2.   346 656 346 576 467 .....  toplam 64 adet değer
.
.
.
.
n.   346 565 343 244 353 .....  toplam 64 adet değer


Böyle bir işlem için ne tür bir depolama kullabilirim? Daha önce hiç uğraşmadım dolayısıyla bana tam olarak ne lazım bilmiyorum.




muhittin_kaplan

text, binary, access,sqlserver diyerek gider.

Mucit23

hocam text derken txt file oluşturup ona mı kaydedeyim?

muhittin_kaplan

csv olabilir o konuda, ama ben olsam localde access de tutardım.
(burada n in limiti önemli)

Mucit23

en şimdilik en fazla 3000 olur diyelim. Ama galiba txt işimi görecek.

muhittin_kaplan

access db daha iyi olur eğer c# kullanacaksan

Mucit23

Abi şimdilik Text dosyası ile yapmaya çalıştım. Az çok başardım da ama bir sorun var. Seri Port'dan sürekli veri geliyor. Ben bu verileri geldiği gibi txt dosyasının içerisine alt alta dizmem gerekiyor.

serialPort1_DataReceived olayının içerisinde en son gelen satırı okuyorum. Bu satırı bir delegate fonksiyon içerisinde daha önce oluşturmuş olduğum bir txt dosyasının içine yazıyorum.

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadLine(); 
            BeginInvoke(new delegateG(RecieveData));
        }

        public void RecieveData()
        {
            FileStream folder = new FileStream(ProjectFolder, FileMode.Open, FileAccess.Write);
            StreamWriter Dosya = new StreamWriter(folder);
            Dosya.WriteLine("Test 1223");
            Dosya.WriteLine(RxString);
            Dosya.Flush();
            Dosya.Close();
        }


Sorun şu. Yazma işleminde sıkıntı yok fakat serialPort1.ReadLine(); fonksiyonu bana en sonki gelen paketi sadece gönderiyor. Ondan önce gelen paketler kayboluyor. txt dosyasının içine baktığımda ise sadece en son gelen paketi görüyorum.

Burada sorun nedir? Bu işlemi doğru bir şekilde nasıl yapabilirim?

vitruvius

Eğer dosyanın sonuna veri eklemek istiyorsan FileMode enumerator'larından FileMode.Append'i kullanmalısın.

Ancak yazma işlemi yaparkan using kullan, bu çok daha kolayına gelir.


  • Dosya yoksa kendi oluşturur.
  • Dosyanın sonuna eklemesini kontrol edersin.
  • Dosyayı kapatır.
  • Hatta exception durumlarında dahi dosyayı kapatır.

using (StreamWriter file = new StreamWriter(fullPath, true))
{
  file.WriteLine(line);
}


Exception'ları kendin yakalarsın.

fullPath dediğim dosyanın gerçek path'i, dosya adı ve uzantısı dahil. İkinci bool parametre ise append, true olunca dosyanın sonuna ekler.

muhittin_kaplan

Vitvirus cevabi vermis,dosyayi write mod da acmissin. Her yazdihinizda yeni bir dosya gibi ele alir. Append mode gelen veriyi en sona ekler.  Sonunda \n varsa yeni satira atar.

Mucit23

Teşekkürler. Şimdi okuldayim ama en kisa zamanda deneyecegim.

Hocam  yalniz using ile tanımladığınız  fonksiyonu anlayamadim. C# çok az biliyorum  bahsettiginiz fonksiyonu nasıl kullanırım ?

vitruvius

İşte yazdığım gibi kullanacaksın =)

Using'in esas amacı işi bittiğinde objeleri Dispose etmesidir. Yani senin kodundaki gibi .Close() fonksiyonlarını falan çağırmana gerek kalmaz. Hatta dediğim gibi exception yakalarken de bununla uğraşmana gerek kalmaz.

Alıntı yapılan: Microsoft - C# Reference (Verdiğim linkten)As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler. The code example earlier expands to the following code at compile time (note the extra curly braces to create the limited scope for the object):

Fonksiyona gelince:

StreamWriter class'ını kullandık. TextWriter kullanarak bir belgeye yazı yazıyor. Detaylarına verdiğim linkten bakabilirsin.

Benim kullandığım Constructor'ı aşağıdaki yapıda:

public StreamWriter(
	string path,
	bool append
)


path: Yazacağın belgenin komple path'i (Belge ismi ve uzantısı dahil). Misal: "C:\\Users\\mucit23\\Documents\\deneme.txt"
append: True: Belgenin sonuna yazar. False: Belgeyi sıfırdan yazar.

WriteLine(string) de StreamWrite ile oluşturduğun belgeye gönderdiğin stringi yazıyor arkasına da satır sonlandırıcıyı koyuyor. Unix playformlarda \n , Unix olmayan platformlarda \r\n .

Yani aşağıdaki fonksiyonu kullanabilirsin.

using System.IO;

/// <summary>
/// Writes one line to the given file.
/// </summary>
/// <param name="filePath">File path, WITHOUT the file name.</param>
/// <param name="fileName">File name, WITHOUT the extension. Extension will be .txt</param>
/// <param name="line">Line to be written.</param>
/// <returns>True: Write successful, False: Write unsuccessful, see the error log.</returns>
public static bool writeOneLineToFile(string filePath, string fileName, string line)
{
   string fullPath = Path.Combine(filePath, fileName + ".txt");

   try
   {
      using (StreamWriter file = new StreamWriter(fullPath, true))
      {
         file.WriteLine(line);
      }
      return true;
   }
   catch (DirectoryNotFoundException ex_DirNotFound)
   {
      MessageBox.Show("Oups, directory is not found while writing a file!");
      return false;
   }
}


Oluşması muhtemel diğer exception'ları da sen yakalarsın.

Mucit23

@vitruvius Teşekkür ederim sayende hallettim.
Kodu şu şekilde düzenledim.
        public static bool writeOneLineToFile(string filename, string line)
        {
            try
            {
                using (StreamWriter file = new StreamWriter(filename, true))
                {
                    file.WriteLine(line);
                }
                return true;
            }
            catch (DirectoryNotFoundException ex_DirNotFound)
            {
                MessageBox.Show("Oups, directory is not found while writing a file!",ex_DirNotFound.Message);
                return false;
            }
        }


Dediğim gibi c# ile anca ufak tefek işler için uğraşmam gerekiyor. Pek bilmiyorum haliyle. Öğrene öğrene işimi hallediyorum.

Mucit23

@vitruvius bir sorunum daha var. Bu konuda da yardımını isteyeceğim yine takılıp kaldım

Hocam TXT dosyası içerisinde sırayla dizmiş olduğum veriyleri okuyup excel'de tabloya aktarmam gerekiyor.
Şuanda Exel dosya yazma işlemlerini hallettim diyebilirim. C# üzerinden excel dosyası oluşturup İstediğim sütüna ve satıra veri yazabiliyorum. Excel dosyası oluşturma işini öğrendim.

Txt dosya okuma işinide yapıyorum. Bunu senin önerdiğin yöntemle yaptım. Txt dosyasından satır satır verileri okuyabiliyorum. Şimdi daha önce konuştuğumuz string parçalama işlemlerini yapmam lazım ama burada takıldım.

Veri okuma ve excele yazmak için aşağıdaki gibi bir public fonksiyon oluşturdum.
        public bool read_and_write_excel()
        {

            string rxdata;
            
            try
            {
                using (StreamReader file = new StreamReader(ProjectFolder, true))
                {
                    rxdata = file.ReadLine();
                    while (rxdata != null)
                    {
                        //string text = rxdata.Split(new char[] { '|', '#' }, StringSplitOptions.RemoveEmptyEntries);  //Burada satır verisi parçalara ayrılacak. 

                    }
                }
                return true;
            }
            catch (DirectoryNotFoundException ex_DirNotFound)
            {
                MessageBox.Show("Okuma İşlemi sırasında bir hata oluştu!", ex_DirNotFound.Message);
                return false;
            }

        }


Daha önce bu işi devC de yapmıştık. Aslında özet olarak aşağıdaki kodları C# da çalışacak şekilde editlemem lazım.
int main ()
{
  char text[265]="1.Deger|607|349|473|758|130|872|744|278|323|109|540|665|492|242|387|803|727|529|340|712|303|469|009|857|760|033|699|378|116|835|097|326|212|667|710|333|379|649|279|021|667|272|793|036|785|245|128|391|294|157|701|353|808|244|568|590|624|296|030|103|322|466|549|224#";
  char *spText;
  spText = strtok (text,"|#");
  while (spText != NULL)
  {
    printf ("%s\n",spText);
    spText = strtok (NULL, "|#");
  }
getch();
  return 0;
}


Şu split fonksiyonunu çözemedim. Bu nasıl çalışıyor. Bu işi en uygun nasıl yaparım?

muhittin_kaplan

#13
mucit gayet basit çalışıyor.

string Text="Deneme;Deneme2;Deneme3;Deneme4;Deneme5";
string[] SplittedText=Text.split(";");



kodu açıklayayım denemedim syntax hatası olabilir.

parametre olarak verilen değer göre böler ve array a atar

console.Writeline(SplittedText[2])
dersem, konsola "deneme3" yazar.

muhittin_kaplan

#14
Düzeltme

                string s = "there is a cat";
                // Split string on spaces.
                // ... This will separate all the words.
                string[] words = s.Split(' ');
                foreach (string word in words)
                {
                    Console.WriteLine(word);
                }

s string inin içindeki boşluklara göre bölüyor.

public static void Main(string[] args)
        {
                string s = "there is a cat";
                // Split string on spaces.
                // ... This will separate all the words.
                string[] words = s.Split(' ');
                foreach (string word in words)
                {
                    Console.WriteLine(word);
                }

            Console.WriteLine(words[2]);
        }


dediğim gibi de çalışıyormuş.