2015-02-07 84 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