2015-02-07 29 views
7

由於幾個晚上,我被這個問題困住了。我在我的應用程序中有SQLite數據庫。我從文件創建了SQLite數據庫。該ERD圖如下所示: enter image description hereSQLite - 使用LINQ檢索數據

現在在我的應用程序創建我的數據庫的連接:

using (var conn = new SQLiteConnection(DB_PATH)) 
{ 
    // retrieving statemets... 
} 

我創建了代表我的數據庫表類:

public class Kantory 
    { 
     public Kantory() 
     { 
      this.kursy = new HashSet<Kursy>(); 
     } 

     [SQLite.PrimaryKey, SQLite.AutoIncrement] 
     public int id_kantory { get; set; } 
     public string nazwa { get; set; } 

     public virtual ICollection<Kursy> kursy { get; set; } 
    } 

public class Waluty 
    { 
     public Waluty() 
     { 
      this.kursy = new HashSet<Kursy>(); 
     } 

     [SQLite.PrimaryKey, SQLite.AutoIncrement] 
     public int id_waluty { get; set; } 
     public string nazwa { get; set; } 

     public virtual ICollection<Kursy> kursy { get; set; } 
    } 

public class Kursy 
    { 
     [SQLite.PrimaryKey, SQLite.AutoIncrement] 
     public int id_kursy { get; set; } 
     public int id_kantory { get; set; } 
     public int id_waluty { get; set; } 
     public decimal kurs { get; set; } 
     public System.DateTime data { get; set; } 
     public int aktualne { get; set; } 

     public virtual Kantory kantory { get; set; } 
     public virtual Waluty waluty { get; set; } 
    } 

正如你所看到的,在kursy表中我有兩個外鍵 - id_kantoryid_waluty

而現在很奇怪和奇怪的事情發生。當我嘗試使用普通的SQL statemets與INNER JOIN語句檢索一些信息 - 它工作得很好!:

using (var conn = new SQLiteConnection(DB_PATH)) 
{ 
    var query = new SQLiteCommand(conn); 
    query.CommandText = "SELECT * FROM Kursy INNER JOIN Kantory ON Kursy.id_kursy=Kantory.id_kantory WHERE Kantory.id_kantory = 1"; 
    var result = query.ExecuteQuery<Kursy>(); 
} 

此代碼工作正常!但是,當我試圖使用LINQ像這樣用我的課:

using (var conn = new SQLiteConnection(DB_PATH)) 
{ 
    var result = conn.Table<Kursy>().Where(k => k.kantory.id_kantory == 1).FirstOrDefault(); 
} 

它拋出我NotSupportedException異常!的消息話題:會員訪問失敗編譯表達

但是當我使用使用LINQ 我的課沒有加入另一個類它的工作原理!:

using (var conn = new SQLiteConnection(DB_PATH)) 
    { 
     var result = conn.Table<Kursy>().Where(k => k.id_kursy == 1).FirstOrDefault(); 
    } 
到底

所以:我的問題是我無法使用LINQ查詢加入更多的表。似乎這種模式在課堂上是錯誤的,但我真的不知道爲什麼...

PS。這是Windows Phone 8.1應用程序,所以我無法使用實體框架。

+1

Sqlite-net不支持外鍵 – ErikEJ 2015-02-07 13:29:00

+0

@ErikEJ,嗯,但是當我使用正常的SQL語句,如上所示使用'SELECT ... FROM ... INNER JOIN ...'時,它可以工作。所以它可能使用外鍵,不是嗎? – XardasLord 2015-02-07 13:35:16

+2

它不會將連接從LINQ轉換爲SQL – ErikEJ 2015-02-07 14:00:40

回答

7

這裏是可用的代碼。它只使用EntityFramework 6.3.1,沒有任何SQLite特定的程序集。

我明白你不想使用實體框架。要想爲此添加一個答案,我們需要知道您正在使用的具體裝配是什麼SQLite。例如,你使用DbLinq

具體來說,什麼程序集包含以下方法?

  • SQLiteCommand.ExecuteQuery<T>()
  • SQLiteConnection.Table<T>()

在任何情況下,這裏是代碼,實體框架的工作。

using System; 
using System.Linq; 
using System.Data.Entity; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 

namespace SQLite 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var conn = new SQLiteConnection(@"C:\linqToSqlite.db")) 
      { 
       SeedEntities(conn); 

       // this is the query that DID work for you 
       var result1 = conn.Kursy 
        .Where(k => k.id_kursy == 1) 
        .FirstOrDefault(); 

       Console.WriteLine(
        string.Format("id_kursy:{0}", result1.id_kursy)); 

       // this is the query that did NOT work for you 
       // it does work here 
       var result2 = conn.Kursy 
        .Where(k => k.kantory.id_kantory == 1) 
        .FirstOrDefault(); 

       Console.WriteLine(
        string.Format("id_kursy:{0}", result2.id_kantory)); 
      } 

      Console.ReadKey(); 
     } 

     private static void SeedEntities(SQLiteConnection conn) 
     { 
      SeedEntities(conn); 
      // make sure two entities exist with the appropriate ids 
      if (!conn.Kantory.Any(x => x.id_kantory == 1)) 
      { 
       conn.Kantory 
        .Add(new Kantory() { id_kantory = 1 }); 
      } 

      if (!conn.Kursy.Any(x => x.id_kantory == 1)) 
      { 
       conn.Kursy 
        .Add(new Kursy() { id_kantory = 1 }); 
      } 

      conn.SaveChanges(); 
     }   
    } 

    public class SQLiteConnection : DbContext 
    { 
     public SQLiteConnection(string connString) : 
      base(connString) {} 
     public DbSet<Kantory> Kantory { get; set; } 
     public DbSet<Kursy> Kursy { get; set; } 
    } 

    public class Kantory 
    { 
     public Kantory() 
     { 
      this.kursy = new HashSet<Kursy>(); 
     } 

     [Key] 
     public int id_kantory { get; set; } 
     public virtual ICollection<Kursy> kursy { get; set; } 
    } 

    public class Kursy 
    { 
     [Key] 
     public int id_kursy { get; set; } 
     public int id_kantory { get; set; } 
     public virtual Kantory kantory { get; set; } 
    } 
} 

恐怕我使用了一種不同於你的技術,因爲我不知道你使用的確切程序集。例如,目前尚不清楚您用於Table<T>()方法的裝配。所以,我用了DbContext.Kursy方法來代替,而以下參考:

  • EntityFramework.dll
  • EntityFramework.SqlServer.dll
  • System.dll
  • System.ComponentModel.DataAnnotations.dll

換句話說,它的工作原理簡單地用的EntityFramework 6.1.3並且不需要任何SQLite特定組件。

對於與您的需求相關的答案,您引用了什麼SQLite具體參考?

+0

謝謝你!在我的情況下,我沒有將我的FK屬性設置爲虛擬,而LINQ未填充它們。例如 'public string Colour_Id {get;組; } [ForeignKey(「Colour_Id」)] public virtual Color Color {get;組; }' – Kris 2015-10-26 06:41:49