2014-11-07 1 views
1

NuGet 패키지 중 하나를 사용 : SQLite.Net-PCL-Win32 플랫폼, SQLite.Net-PCL-XamarinIOS 플랫폼 또는 SQLite.Net-PCL XamarinAndroid 플랫폼 select 일반적으로 특히 LINQ 또는 원시 SQL에서 데이터베이스를 선택할 때마다 기본값을 포함하는 객체 인 것처럼 보입니다.SQLite.Net-PCL 이상한 선택 동작

using SQLite.Net.Attributes; 

namespace ConsoleApplication1 
{ 
    public class Entity 
    { 
     public Entity() { } 

     [PrimaryKey, AutoIncrement] 
     public int Id { get; set; } 

     public string Data { get; set; } 

     public int IntData { get; set; } 

     public bool BoolData { get; set; } 

     public override string ToString() 
     { 
      return string.Format("Id: {0}, Data: {1}, IntData: {2}, BoolData: {3}", Id, Data, IntData, BoolData); 
     } 
    } 
} 

그래서 나는 일에 그것을 얻을 수 있었던 유일한 방법은에 있었다 :

using System; 
using System.Linq; 
using SQLite.Net; 
using SQLite.Net.Platform.Win32; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Open a connection to the database 
      using (var database = new SQLiteConnection(new SQLitePlatformWin32(), "db.db")) 
      { 
       // Create a simple table 
       database.CreateTable<Entity>(); 

       // Add a simple record to it each time we start the application 
       database.Insert(new Entity { Data = Guid.NewGuid().ToString(), BoolData = true, IntData = 5 }); 

       Console.WriteLine("---------> Inserted item:"); 

       // Display all our records 
       foreach (var e in database.Table<Entity>()) 
       { 
        Console.WriteLine(e); 
       } 

       Console.WriteLine(Environment.NewLine); 
       Console.WriteLine("---------> Linq select Ids:"); 

       // For every record we'll select the Id field - this is not working 
       foreach (var e in database.Table<Entity>().Select(e => e.Id)) 
       { 
        Console.WriteLine(e); 
       } 

       Console.WriteLine(Environment.NewLine); 
       Console.WriteLine("---------> Id by scalar query:"); 

       // Let's try going after a value explicitly - this is fine 
       var r1 = database.ExecuteScalar<int>("SELECT Id FROM Entity WHERE Id == 1"); 

       Console.WriteLine(r1); 
       Console.WriteLine(Environment.NewLine); 
       Console.WriteLine("---------> Ids by query:"); 

       // So lets try going after our Id field from a query - this still dosen't work 
       foreach (var e in database.Query<int>("SELECT Id FROM Entity")) 
       { 
        Console.WriteLine(e); 
       } 

       Console.WriteLine(Environment.NewLine); 
       Console.WriteLine("---------> Linq select Ids after force to memory:"); 

       // Now lets try forcing a where to execute before performing the select - this works but it's bad 
       foreach (var e in database.Table<Entity>().Where(e => e.IntData == 5).ToList().Select(e => e.Id)) 
       { 
        Console.WriteLine(e); 
       } 

       Console.ReadKey(); 
      } 
     } 
    } 
} 

법인은 단순한 POD입니다 : 여기

내 문제 보여주기 위해 예 콘솔 응용 프로그램입니다 우리가 관심이없는 BLOB 등을 포함하는 데이터를 가질 수있는 경우에 이것은 나쁜 것입니다.

의도적 인 동작입니까? 나는 뭔가를 놓쳤는가?

답변

0

처럼 찾고 있던 나는 내가 SQLIteConnection.Query를 통해를 쿼리 된 개별 필드를 포함하는 POD 클래스 ("일부 SQL 쿼리") 방법을 사용하여이 문제를 해결. 여기서 T는 관심 분야가 포함 된 특정 POD입니다. 필드 이름이 SELECT 뒤에 나열된 필드와 일치하는 한 필드 이름을 맵핑 할 수있었습니다.

각 쿼리 결과를 나타 내기 위해 여러 클래스를 생성하고 싶지 않기 때문에 아직까지는 이상적이라고 생각합니다. 우리가 Anonymous Types으로 할 수있는 일이 있을지 모르지만, 그것은 런타임시 지저분하고 값 비쌉니다.

0

흠 레코드를 찾았는지 여부와 관계없이 Entity 클래스의 필드가 기본값을 사용하지 않는 참조 유형이기 때문에 결과 (매핑 된 객체)를 반환 할 수 있습니다. 내 응용 프로그램에서 나는 약간 다른 방식으로 레코드를 선택했다. 아마도 나는 잘못 (성능 현명함)하고 있었지만 비슷한 문제는 없었을 것이다. 기본적으로 내 쿼리

int id = GetID(); 
using(var connection = Db.getConnection()) 
{ 
    var result = connection.Table<Entity>().where(x=> x.id == id).firsOrDefault(); 
    if(result != null) 
    { 
     //record found 
    } 
    else 
    { 
     //not found 
    } 
} 
+0

여전히 개체를 메모리에로드하기 때문에 작동합니다. 내 문제는 개체를 메모리에 가져 오기 전에 필드를 선택하려고 할 때입니다. – Nuluvius