none
SQLite Bağlantı Sorunu RRS feed

  • Soru

  • Merhabalar, geliştirdiğim projede SQLite veritabanı dosyama bağlanamıyorum. Sorunun detayına inecek olursak problem şöyle;

    Form1'de aşağıdaki kod ile bağlantı gerçekleştire biliyorken Form2'de aynı kod ile bağlantı sağlanamıyor. 

    SQLiteConnection con = new SQLiteConnection("Data Source=data.db");
    //from1'de yazan bağlantı cümlesi.
    
    SQLiteConnection baglanti = new SQLiteConnection("Data Source=data.db");
    //form2'deki bağlantı cümlesi, üsteki ile aynı.

    Proje Herhangi bir hata vermiyor sadece form2'deki datagridview nesneme tablolarım gelmiyor o kadar. 2 Gün boyunca deneme yanılma ile yaptığım değişikler ile aşağıdaki kod sayesinde bağlantı kodunu çalıştırmayı başardım.

    SQLiteConnection baglanti = new SQLiteConnection("Data Source=c:\\data.db");
    //tek değişiklik veritabanı dosyamı C dizinin hemen altına koymak. Sanırım veritabanı dosyasına projenin olduğu yerden erişemiyor yada tam adres girilmesini istiyor olabilir.
    Bu hali ile Form2'deki datagridview nesneme tablolarımı getirebildim. Fakat sorun burada başlıyor, form1'de çalışan kod Form2'de neden çalışmadı ? bunu anlayamadım. Birde ben veritabanı dosyamı projemin başlatıldığı yer olan bin\Debug içinden okusun istiyorum. Bu sayede projeyi götürdüğüm her yerden çalıştırabilirim. İnternette araştırmam sonucu başka bağlantı metodu bulamadım. İstediğim şey projenin olduğu dizinden dosya okumasını sağlayacak başka bir bağlantı metodu var mı bildiğiniz ? Yardımcı olacaklara şimdiden teşekkürler. Yardımlarınızı bekliyorum.
    16 Eylül 2019 Pazartesi 09:29

Tüm Yanıtlar

  • string dosyaDizini = AppDomain.CurrentDomain.BaseDirectory.ToString() + "ProjectDb.s3db";

    if (!File.Exists(dosyaDizini))
                {
                    SQLiteConnection.CreateFile("ProjectDb.s3db");

    }

    Başlangıçta böyle bir kontrol ile istediğin klasöre oluşturma yapabilirsin



    Altan Özdemir

    16 Eylül 2019 Pazartesi 09:51
  • Bir path yazarken spesifik bir adres belirtmiyorsan örneğindeki gibi data.db varsayılan olarak exe'nin çalıştığı dizini referans alacak (.\data.db gibi). Dolayısıyla connection string'inde bir hata yok.

    Konuyla doğrudan bir alakası olmayabilir ama olası bir hatan var; connection command gibi durumlarda using blokları içinde kullanırsan başka bir bağlantıyla çakışma, bağlantıyı kapatmayı unutma gibi şeylerle karşılaşmazsın.

    string connSTring = "Data Source=example.db; Version=3;";
    
    using (var conn = new SQLiteConnection(connSTring))
    {
        conn.Open();
    
        ...
    }

    Hatta veritabanından örnek bir şeyler okuyalım

    string connSTring = "Data Source=example.db; Version=3;";
    
    using (var conn = new SQLiteConnection(connSTring))
    {
        conn.Open();
    
        using (var comm = new SQLiteCommand(conn))
        {
            comm.CommandText = "SELECT rowid, * FROM products";
    
            using (var reader = comm.ExecuteReader())
            {
                if (reader.HasRows)
                {
                    var products = new List<Product>();
    
                    while (reader.Read())
                    {
                        var newProduct = new Product()
                        {
                            RowId = (long)reader["rowid"],
                            Manufacturer = (string)reader["manufacturer"],
                            Name = (string)reader["name"],
                            Version = (long)reader["version"],
                            Count = (long)reader["count"],
                            Price = (long)reader["price"]
                        };
                        products.Add(newProduct);
                    }
    
                    ProductsListView.ItemsSource = products;
                }
                else
                {
                    MessageBox.Show("There is no result on products table", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }
        }
    }

    Şimdi senin asıl sorununa gelelim, SQLite dosya tabanlı/mantığında çalışan bir veritabanıdır. Bütün veriler doğrudan erişebildiğin bir dosyanın içinde yer alır, portable vs. Bunun en büyük dezavantajı birden fazla uygulamanın veya işlemin aynı dosyayı kullanamamasıdır. Yani sen bir connection başlatıp sonra bir tane daha başlatırsan diğer connection dosyanın erişilebilir olmasını bekler. Timeout olana kadar hata görmezsin. Yukarıdaki örnekteki gibi using ile çalışırsan sorunun çözülür.

    Dikkat edersen CRUD işlemlerini yaptığın an examle.db.lock şeklinde bir dosya daha oluşur. Bunun anlamı şu, ben şuan meşgulüm daha sonra dene. İşlem bittiğinde bu dosya silinir ve yeniden erişilebilir olur.

    Şu örnekleri de inceleyebilirsin.


    TR| Sorunuzun yanıtı bu ise "Yanıt Olarak Öner" olarak işaretleyin, eğer faydalı bir yorum ise "Oy Ver"erek forumun işleyişine katkıda bulunabilirsiniz. EN| If this is the answer to your problem, mark "Propose as Answer" and if it is helpful, you can contribute to the workig of the forum by "Voting".


    • Düzenleyen Egoist Developer 16 Eylül 2019 Pazartesi 10:06 imla hatası düzeltme
    16 Eylül 2019 Pazartesi 10:05
  • "Bağlantı saglanamiyor"dan kastiniz ne? Baglantinin sağlanıp saglanmadigina nasil hukmediyorsunuz ve ne hata alıyorsunuz? Baglantinin saglanamama nedeni sadece connection string ile ilgili olmayabilir (egoistdeveloper değinmiş aslinda, benimki onu tekrarlamak oldu).

    Tavsiyem, SQLite bağlantı cümlelerinde, boyle sadece dosya adini degil, tam yolunu belirtmeniz. Bu arada tam yolu derken, dosyanın yeri olarak c:\ ya da debug dizini gibi yerler secmeyin. debug dizinini secince, executable dosyanızla ayni yerde olacagini söylüyorsunuz, iyi güzel hoşta da, kullanicilar uygulamalri genelde "Program Files" altına kurar (Windows'un önerisi de o). Orası ise, Microsoft bizlerden cok akilli ya, bizi koruduğundan ReadOnly. Onerilen yer AppData özel klasörü:

    var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    Console.WriteLine(path);
    var dbName = Path.Combine(path, "myDb.s3db");
    Console.WriteLine(dbName);

    Istersen IsolatedStorage'i de kullanabilirsin. Ya da belli bir dizin yaratır onu kullanırsın (ornegin Documents\Public altında ya da dogrudan c:\UygulamaAdiData gibi - secnekler sonsuz).



    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    16 Eylül 2019 Pazartesi 11:34
    Yanıtlayıcı
  • Merhaba,

    Hata alıp almama konusunu burada bahsetmiştim. "Proje Herhangi bir hata vermiyor sadece form2'deki datagridview nesneme tablolarım gelmiyor o kadar."

    Bağlantı sağlanıp sağlanmadığı konusuna da şuradan hükmettiğimden bahsettim. "Form1'de aşağıdaki kod ile bağlantı gerçekleştire biliyorken Form2'de aynı kod ile bağlantı sağlanamıyor."

    Konuya dönecek olursak @egoistdeveloper hocamızın söylediği gibi "birden fazla uygulamanın veya işlemin aynı dosyayı kullanamamasıdır" konusunda araştırma yapıyorum, sanırım bu konuda haklı çünkü tüm örneklerde using bloğu kullanılmış. Bu şekilde ilerlemeye çalışacağım. Bir gelişme olur ise buradan yazarım. İlginize ve alakanıza teşekkür ederim.

    Bu arada yeni bağlantı şeklim şu şekilde ;

     string sql_yolu = $"Data Source={Application.StartupPath}\\data.db; Version=3; default timeout=10000; Poling=True; Max Pool Size=100;";

    umarım doğru bir bağlantı yoludur.

    16 Eylül 2019 Pazartesi 12:10
  • Merhaba,

    Hata alıp almama konusunu burada bahsetmiştim. "Proje Herhangi bir hata vermiyor sadece form2'deki datagridview nesneme tablolarım gelmiyor o kadar."

    Bağlantı sağlanıp sağlanmadığı konusuna da şuradan hükmettiğimden bahsettim. "Form1'de aşağıdaki kod ile bağlantı gerçekleştire biliyorken Form2'de aynı kod ile bağlantı sağlanamıyor."

    Konuya dönecek olursak @egoistdeveloper hocamızın söylediği gibi "birden fazla uygulamanın veya işlemin aynı dosyayı kullanamamasıdır" konusunda araştırma yapıyorum, sanırım bu konuda haklı çünkü tüm örneklerde using bloğu kullanılmış. Bu şekilde ilerlemeye çalışacağım. Bir gelişme olur ise buradan yazarım. İlginize ve alakanıza teşekkür ederim.

    Bu arada yeni bağlantı şeklim şu şekilde ;

     string sql_yolu = $"Data Source={Application.StartupPath}\\data.db; Version=3; default timeout=10000; Poling=True; Max Pool Size=100;";

    umarım doğru bir bağlantı yoludur.

    Daha once de söylediğim gibi, içerisinde path olmayan sekilde ("data.db" gibi), ya da uygulamanın yerini baska bir sekilde kullanacak (Application.StartupPath, AppDomain.CurrentDomain.BasePDirectory ... gibi) baglanti cümleleri kullanmayınız. Burada calisip, sonra uygulamaya baska yere kurduğunuzda calismayabilir.



    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.

    16 Eylül 2019 Pazartesi 13:31
    Yanıtlayıcı