Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 22

0
votes
answers
32 views
+10

SQLite UPDATE命令不更新數據庫

-1

我想在用戶離開視圖後保存用戶的ScrollView位置。SQLite UPDATE命令不更新數據庫

我這樣做是通過嘗試捕獲getScrollY在之內的位置並將其保存到數據庫中,然後在用戶返回時檢索它。

我可以成功地添加和檢索位置(Log.i("scrolly", Integer.toString(scrollY))按預期返回),但ScrollView不會跳到正確的位置。

StoryBodyActivity的部分:

public class StoryBodyActivity extends AppCompatActivity { 

    private TextView storyBodyTextView; 
    private ScrollView storyBodyScrollView; 
    public int storyID; 
    Parcelable state; 
    int scrollY; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_story_body, menu); 
     return true; 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_story_body); 

     Bundle extras = getIntent().getExtras(); 

     String story = extras.getString("story"); 
     storyID = extras.getInt("story_id"); 
     Log.i("stories", Integer.toString(storyID)); 

     storyBodyTextView = (TextView) findViewById(R.id.story_body_text_view); 
     storyBodyScrollView = (ScrollView) findViewById(R.id.story_body_scroll_view); 

     DatabaseHelper db = new DatabaseHelper(this); 
     scrollY = db.getScrollPosition(storyID); 
     Log.i("scrolly", Integer.toString(scrollY)); 

     storyBodyScrollView.scrollTo(0, scrollY); 

     String storyBody = db.getStoryBody(storyID); 

     storyBodyTextView.setText(Html.fromHtml(storyBody)); 

     if(state != null) { 
      Log.d("pause", "trying to restore textview state.."); 
      storyBodyTextView.onRestoreInstanceState(state); 
     } 

     int scroll = storyBodyScrollView.getScrollY(); 
     Log.i("scroll", Integer.toString(scroll)); 

    } 

    @Override 
    public void onPause() { 

     scrollY = storyBodyScrollView.getScrollY(); 
     Log.i("scroll", Integer.toString(scrollY)); 
     Log.i("insert", Integer.toString(storyID)); 
     DatabaseHelper db = new DatabaseHelper(this); 
     db.setScrollPosition(scrollY, storyID); 
     super.onPause(); 
    } 

} 

我DatabaseHelper的部分:

public class DatabaseHelper extends SQLiteAssetHelper { 

    private static final int DATABASE_VERSION = 1; 

    private static final String DATABASE_NAME = "database9.db"; 
    private static final String BOOKS = "books"; 
    private static final String AUTHORS = "authors"; 

    public DatabaseHelper (Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     setForcedUpgrade(); 
    } 

    public int setScrollPosition(int scrollY, int storyID) { 

     String insertQuery = "UPDATE " + BOOKS + " SET scroll_position = '" + scrollY + "' WHERE id = '" + storyID + "'"; 
     Log.i("insert", insertQuery); 
     SQLiteDatabase db = this.getWritableDatabase(); 
     db.execSQL(insertQuery); 

     return 0; 

    } 

    public int getScrollPosition(int storyID) { 

     int scrollPosition = 0; 

     String selectQuery = "SELECT scroll_position FROM " + BOOKS + " WHERE id = '" + storyID + "'"; 

     SQLiteDatabase db = this.getWritableDatabase(); 
     Cursor cursor = db.rawQuery(selectQuery, null); 

     // looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       scrollPosition = cursor.getInt(0); 
      } while (cursor.moveToNext()); 
     } 

     return scrollPosition; 

     } 
} 

UPDATE:

我的架構:

CREATE TABLE "books" (
`id` INTEGER NOT NULL, 
`title` TEXT, 
`author_id` INTEGER, 
`collection` TEXT, 
`body` TEXT, 
`scroll_position` INTEGER, 
PRIMARY KEY(`id`)) 
+0

那麼,我以前的評論回答你的問題。 –

沙发
0
0

在您的INSERT命令中,您傳遞的是字符串作爲id,而它期望整數

String insertQuery = "UPDATE " + BOOKS + " SET scroll_position = '" + scrollY + "' WHERE id = '" + storyID + "'"; 

你看? storyID作爲字符串傳遞("' WHERE id = '" + storyID + "'")!
單引號將該id標記爲字符串。

如果您創建一個整數列,它將永遠不會匹配一個字符串。

CREATE TABLE "books" (
`id` INTEGER NOT NULL, 
`title` TEXT, 
`author_id` INTEGER, 
`collection` TEXT, 
`body` TEXT, 
`scroll_position` INTEGER, 
PRIMARY KEY(`id`)) 

id字段被創建爲一個整數(這很好)。
但是你不能在你的命令中傳遞一個字符串(在你的查詢中)。

編輯

您還傳遞scroll_position領域。
這是一個整數。 而這也是行不通的。

+0

謝謝 - 我刪除了單引號,但我遇到同樣的問題 – Sebastian

+0

因此,沒有與傳入的ID匹配。確保傳入的ID存在於表中。請注意,ListView選擇的索引不一定匹配您的表格行ID。 –

+0

雖然我的代碼成功記錄了'scrollY'的輸出,但是當我在數據庫瀏覽器中查看錶時,沒有'scroll_position'的值。 – Sebastian

0
votes
answers
29 views
+10

sqlite數據庫列的總和值

-2

我想要列的總和值,但我想通過跳過第一個值並開始彙總連續的第二個值來總結這些值。我的代碼sqlite數據庫列的總和值

public int sumColum(){ 
    SQLiteDatabase db = this.getReadableDatabase(); 
    Cursor result = db.rawQuery("select sum(PRICE) from wedding_table", null); 

    if(result.moveToNext()) 
     return result.getInt(0); 

    return 0; 
} 
+2

以及如何確定的第一個記錄? –

+2

樣本數據和期望的結果可能有助於澄清你想要做什麼。 –

沙发
0
0

SQL表代表無序套,所以沒有第一價格,除非另一列指定的順序。

如果你指的是最高或最低的價格,那麼這是很容易的 - 假設有沒有重複:

select sum(PRICE) - min(price) 
from wedding_table; 
+0

我想總結第二個,第三個,第四個等到列中的最後一個值 – Djj

0
votes
answers
38 views
+10

共享SQLite數據庫信息

-2

我有一個關於我的應用程序的問題。當我在搜索sqlite數據庫的概念和優勢時,我發現SQLite無服務器,或者在使用SQLite時不必處理服務器。共享SQLite數據庫信息

我的問題是,如果SQLite是無服務器的,兩臺或多臺設備如何在沒有服務器的情況下在我的應用程序中共享信息?

+0

不使用SQLite。只需(...)通過webservices在服務器上使用遠程數據庫。 –

+0

android中的Sqlite意味着它在本地保存數據!例如何時保存whatsapp消息,即使沒有互聯網,您仍可以訪問它們! – Xenolion

+0

http://www.sqlite.org/whentouse.html –

沙发
0
0

想要在創建服務器/客戶端場景的設備之間共享任何內容。即某件事從一個設備提供給客戶端,另一個設備。

SQLite可能不是理想的解決方案,因爲不包含客戶端 - 服務器方面,所以您必須編寫自己的服務器和客戶端代碼,這很可能不會很簡單。

Firebase可能是最簡單的解決方案,因爲它是單個SDK,由Google託管/提供。 This link - Add Firebase to Your Android Project - may be of interest

0
votes
answers
59 views
+10

爲什麼我的單元測試試圖插入一個記錄,當我不問它?

0

我正在使用rails 5和devise。我正在爲我的控制器編寫一些單元測試,但我正在跑到一堵牆上。以下是我正在試圖測試爲什麼我的單元測試試圖插入一個記錄,當我不問它?

# GET /issues/new 
    def new 
    unless user_signed_in? 
     redirect_to new_user_session_path 
    end 
    @issue = Issue.new(stop_onestop_id: params[:stop_id], line_onestop_id: params[:line_id]) 
    end 

這裏的方法就是我寫

# issues_controller_test.rb 
class IssuesControllerTest < ActionDispatch::IntegrationTest 

    include Devise::Test::IntegrationHelpers 

    test "logged in should get issues page" do 
    sign_in users(:one) 
    test_stop_id = 1 
    test_line_id = 1 
    get new_issue_url, params: {stop_id: test_stop_id, line_id: test_line_id} 
    assert_equal test_stop_id, @issue.stop.id 
    assert_equal test_line_id, @issue.line.id 
    assert_response :success 
    end 
end 

然而測試,當我運行它,我得到以下例外...

localhost:Caravan-App davea$ rails test 
Running via Spring preloader in process 9509 
Run options: --seed 48437 

# Running: 

E 

Error: 
IssuesControllerTest#test_logged_in_should_get_issues_page: 
ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: UNIQUE constraint failed: users.email: INSERT INTO "users" ("created_at", "updated_at", "id") VALUES ('2017-12-27 19:07:16.234345', '2017-12-27 19:07:16.234345', 298486374) 



bin/rails test test/controllers/issues_controller_test.rb:6 



Finished in 0.320746s, 3.1177 runs/s, 0.0000 assertions/s. 

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips 

沒有我要求創建新記錄的位置,爲什麼我的測試試圖插入一個?

+1

'用戶(:一個)'抓住測試夾具。你有沒有檢查你的'users.yml'夾具文件?你可能會有一些裝置違反了獨特的電子郵件限制。 –

+0

嘗試將'redirect_to new_user_session_path'更改爲'redirect_to new_user_session_path並返回' –

+0

@DerekHopper,使用taht fixture文件進行良好調用。這確實是問題。 – Dave

沙发
0
1

在行sign_in users(:one),users(:one)正在取夾具。看到這告訴我你正在使用一個燈具文件。

您的項目中有一個文件users.yml,它定義了一些用戶進行測試。它看起來像ActiveRecord::RecordNotUnique異常來自那裏。更具體地說,用戶固定裝置似乎違反了對users.email的唯一性約束。

如果您通過爲每個用戶提供一個唯一的電子郵件地址來修復您的users.yml文件,那麼您應該很好。

0
votes
answers
65 views
+10

VS2017 SQLite不寫數據到數據庫

0

我有下面的代碼,它不會拋出異常,但它也不會更新SQLite數據庫,有兩種方法,一種是由Update按鈕調用的,並從GridView獲取更新的數據控制並寫入SQLite文件。實際上都沒有更新數據庫。在更新方法中,有幾次嘗試使用不同的技術來嘗試寫入數據。我將整個事件包含在上下文中,並且功能被分解爲代碼的不同部分。它使用的是Metro Framework,但我認爲這對數據庫代碼沒有什麼影響。VS2017 SQLite不寫數據到數據庫

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

using MetroFramework.Forms; 
using MetroFramework; 

using System.Data.SQLite; 


namespace MetroTestApp 
{ 
    public partial class Form1 : MetroFramework.Forms.MetroForm 
    { 
     static List<String> entries = new List<string>(); 
     private BindingSource masterBindingSource = new BindingSource(); 
     private BindingSource detailsBindingSource = new BindingSource(); 
     DataSet data = new DataSet(); 

     static string DbConnectionString = @"Data Source=Emp.db;Version=3;"; 
     static SQLiteConnection dbc = new SQLiteConnection(DbConnectionString); 

     public SQLiteDataAdapter departmentDataAdapter; 
     SQLiteDataAdapter empDataAdapter; 

     DataRelation relation; 
     SQLiteCommandBuilder cmdBuilder = new SQLiteCommandBuilder(); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void metroTile1_Click(object sender, EventArgs e) 
     { 
      MetroFramework.MetroMessageBox.Show(this, "OK", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 

     private void metroTile2_Click(object sender, EventArgs e) 
     { 
      MetroFramework.MetroMessageBox.Show(this, "Stop", "Message", MessageBoxButtons.OKCancel, MessageBoxIcon.Stop); 
     } 

     private void metroGrid2_CellContentClick(object sender, EventArgs e) { } 

     private void metroButton2_Click(object sender, EventArgs e) { } 

     private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      dbc.Close(); 
      cmdBuilder.Dispose(); 
      departmentDataAdapter.Dispose(); 
      empDataAdapter.Dispose(); 
      masterBindingSource.Dispose(); 
      empDataAdapter.Dispose(); 
      data.Dispose(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     // string DbConnectionString = @"Data Source=Emp.db;Version=3;"; 
     // using (SQLiteConnection dbc = new SQLiteConnection(DbConnectionString)) 
       try 
       { 
        dbc.Open(); 

        departmentDataAdapter = new SQLiteDataAdapter("select * from DEPARTMENT", dbc); 
        empDataAdapter = new SQLiteDataAdapter("select * from EMP", dbc); 

        departmentDataAdapter.Fill(data, "DEPARTMENT"); 
        empDataAdapter.Fill(data, "EMP"); 

        DataRelation relation = new DataRelation("EMPDPEP", data.Tables["DEPARTMENT"].Columns["DEPNO"], data.Tables["EMP"].Columns["DEPNO"]); 
        data.Relations.Add(relation); 

        masterBindingSource.DataSource = data; 
        masterBindingSource.DataMember = "DEPARTMENT"; 
        detailsBindingSource.DataSource = masterBindingSource; 
        detailsBindingSource.DataMember = "EMPDPEP"; 

        DEPGridView.DataSource = masterBindingSource; 
        EMPGridView.DataSource = detailsBindingSource; 

        DEPGridView.AutoResizeColumns(); 
        EMPGridView.AutoResizeColumns(); 
       } 
       catch (SQLiteException ex) 
       { 
        MetroFramework.MetroMessageBox.Show(this, "Stop", ex.Message.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Stop); 
       } 
     } 

     private void metroButton3_Click(object sender, EventArgs e) 
     { 
      //dbc.Open(); 

      //departmentDataAdapter = new SQLiteDataAdapter("select * from DEPARTMENT", dbc); 
      //empDataAdapter = new SQLiteDataAdapter("select * from EMP", dbc); 


      SQLiteCommandBuilder cb=new SQLiteCommandBuilder(empDataAdapter); 
      empDataAdapter.DeleteCommand = cb.GetDeleteCommand(true); 
      empDataAdapter.UpdateCommand = cb.GetUpdateCommand(true); 
      empDataAdapter.InsertCommand = cb.GetInsertCommand(true); 

      SQLiteCommandBuilder cb1 = new SQLiteCommandBuilder(departmentDataAdapter); 
      departmentDataAdapter.DeleteCommand = cb1.GetDeleteCommand(true); 
      departmentDataAdapter.UpdateCommand = cb1.GetUpdateCommand(true); 
      departmentDataAdapter.InsertCommand = cb1.GetInsertCommand(true); 

      // MetroFramework.MetroMessageBox.Show(this, cb.GetUpdateCommand().ToString(), "OK", MessageBoxButtons.OK, MessageBoxIcon.Information); 

      empDataAdapter.AcceptChangesDuringUpdate = true; 
      departmentDataAdapter.AcceptChangesDuringUpdate = true; 

      DataTable dt = new DataTable(); 
      empDataAdapter.Fill(dt); 
      empDataAdapter.Update(dt); 

      data.AcceptChanges(); 

      empDataAdapter.Update(data, "EMP"); 
      departmentDataAdapter.Update(data, "DEPARTMENT"); 
      empDataAdapter.Update(data.Tables["EMP"]); 
      departmentDataAdapter.Update(data.Tables["DEPARTMENT"]); 


      dt.Dispose(); 
      cb.Dispose(); 
      cb1.Dispose(); 
      dbc.Close(); 

     } 

     private void metroButton4_Click(object sender, EventArgs e) 
     { 
      dbc.Open(); 
      DataTable t; t = data.Tables["DEPARTMENT"]; 
      DataRow newRow; 
      newRow = t.NewRow(); 

      newRow["DEPNO"] = 10; newRow["DEPNAME"] = "GAMES"; 

      t.Rows.Add(newRow); 
      data.AcceptChanges(); 
      DEPGridView.Refresh(); 
      dbc.Close(); 
      t.Dispose(); 

     } 
    } 
} 
沙发
0
1

請看看你的代碼

 DataTable dt = new DataTable(); 
     empDataAdapter.Fill(dt); 
     empDataAdapter.Update(dt); 

你所得到的數據和寫入直接到數據庫的這一部分。如果你不改變任何東西,你就不會在數據庫中看到任何改變。我沒有看到這個代碼

點的的代碼遵循這一

 data.AcceptChanges(); 

     empDataAdapter.Update(data, "EMP"); 
     departmentDataAdapter.Update(data, "DEPARTMENT"); 
     empDataAdapter.Update(data.Tables["EMP"]); 
     departmentDataAdapter.Update(data.Tables["DEPARTMENT"]); 

的接受改變,標誌着所有記錄作爲沒有改變。因此,您的DataAdapter.Update不會看到任何更改的記錄發送到數據庫。我會將該行代碼移動到DataAdapter.Updates之後,然後再次嘗試更新記錄。

empDataAdapter.Update(data, "EMP"); 
    departmentDataAdapter.Update(data, "DEPARTMENT"); 
    empDataAdapter.Update(data.Tables["EMP"]); 
    departmentDataAdapter.Update(data.Tables["DEPARTMENT"]); 

    data.AcceptChanges(); 
+0

謝謝,解決了這個問題。正如你所說,有意義的是,Update()需要在記錄更改後運行。並感謝您閱讀這麼大的一段代碼。 –

0
votes
answers
41 views
+10

每個線程一個SQLiteConnection?

6

我使用的是來自system.data.sqlite.org的SQLite每個線程一個SQLiteConnection?

我們需要從多個線程(出於各種原因)訪問數據庫。我讀了很多關於sqlite線程安全功能(默認同步訪問模式對我來說很好)。

我不知道是否可以簡單地打開每個線程的連接。是這樣的可能嗎?我真的不關心比賽條件(請求尚未插入的東西)。我只感興趣的是可以使用每個線程一個對象SQLiteConnection來訪問數據。

沙发
0
3

是的。事實上,這是正確的方式,因爲SQLite不是線程安全的(默認情況下,您可以使用某些選項進行線程安全編譯)。而只是爲了確保它的工作原理:在一些小的網站正在使用SQLite的,所以多線程有:)

這裏的更多信息:http://www.sqlite.org/faq.html#q6

板凳
0
4

由於您使用每個線程一個單獨的連接,你應該罰款。

docs

注意SQLiteConnection實例不保證線程安全 。您應該同時避免在幾個 線程中使用相同的 SQLiteConnection。建議每個線程打開一個新的連接 ,並在工作完成時關閉它。

0
votes
answers
31 views
+10

如何在android工作室中成功發送消息時斷開while循環

1

我正在製作Android應用程序,其中我使用Android服務發送消息while(true)。我將這些消息存儲在sqlite數據庫中。該消息應該只發送一次。我怎樣才能做到這一點?如何在android工作室中成功發送消息時斷開while循環

我的問題是,我如何獲得消息發送ID哪些消息被髮送?

這裏是我的消息代碼:

while (true) { 
    new SendJobs().execute(Numbers);       
} 
+0

你如何定義'那個消息'?也就是說,什麼使消息與其他消息一樣? –

+0

你可以檢查這[鏈接](https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a)到(asyncTask) –

+0

這是我的asynctask代碼: while(true){ifId = JobNumbersId} { String [] jobsNumbers = numbers.toArray(new String [numbers.size()]); new SendJobs()。execute(jobsNumbers);其他{ 中斷; } } } –

沙发
0
0

您已經將其存儲在數據庫嗎?

所以,你可以確保信息只發送一次,通過執行以下操作

  1. 改變用布爾列數據庫(如isSent)
  2. 發送該消息後,更新列到true

所以,如果你正在運行的異步任務中獲得的信息,記住選擇isSent =「假」

對於消息發送ID

使用信息表的主鍵。

0
votes
answers
33 views
+10

沒有WAL文件的核心數據.sqlite備份可以恢復到WAL模式嗎?

1

請耐心等待 - 我會嘗試在這個問題中使用正確的術語。我有一個iOS應用程序,允許用戶現在創建其Core Data支持的.sqlite數據庫的備份。出於某種原因,遙想當年,我爲journal_mode爲「MEMORY」設置選項編譯指示,這意味着每個已經取得了過去幾年的備份沒有WAL或SHM文件。我正在重寫我的所有數據庫代碼,並且我知道iOS的當前默認journal_mode是「WAL」。當我導入與journal_mode「MEMORY」做了備份,我想與該文件在WAL模式(我希望所有新的備份是一樣的 - 在WAL模式)莫名其妙地結束了,但我不知道,如果這甚至有可能。一個沒有WAL或SHM文件的.sqlite可以被迫開始創建它們嗎?我試圖用NSPersistentStore方法來創建備份,現在恢復的數據,看完記得,在整個過程中使用的選項(即journal_mode)需要保持一致(我將發佈的鏈接,這一點,如果我能找到它)。我相信,因爲我沒有WAL文件,所以我需要使用「MEMORY」或「DELETE」journal_mode進行導入。但是,我不確定這是否意味着該文件將永遠不需要WAL文件就能運行,或者我可以做些什麼來使其在WAL模式下運行。我希望這是有道理的 - 這對我來說有點令人困惑,但我希望對如何解決這個問題有任何想法。沒有WAL文件的核心數據.sqlite備份可以恢復到WAL模式嗎?

沙发
0
2

您可以隨時更改數據庫的日誌模式,只要你有獨佔訪問;只需打開它,然後執行PRAGMA。 (事實上??,這是爲了讓WAL模式的唯一方法。)

請注意,只有WAL模式的持久存儲在數據庫中的文件;任何其他日記模式都是連接的屬性;當打開非文件WAL時,它默認處於DELETE模式。

+0

真棒。謝謝。 – SAHM

0
votes
answers
22 views
+10

如何使用Anko檢查記錄是否存在?

0

我正在學習使用anko從sqlite中獲取數據。我可以成功打印數據(如果存在記錄),但是當數據不存在時,我的應用程序總是會崩潰。如何使用Anko檢查記錄是否存在?

錯誤說:

parseSingle只接受一次入境

我知道錯誤的確切意思,我只是不知道如何解決它遊標。

這裏是查詢代碼:

fun getUserByUid(uid: Int): UserModel 
{ 
    val data = context.database.use { 
     val db = context.database.readableDatabase 
     val columns = UserModel.COLUMN_ID + "," + UserModel.COLUMN_NAME + "," + UserModel.COLUMN_API_KEY 

     val query = db.select(UserModel.TABLE_NAME, columns) 
       .whereArgs("(uid = {userId})", 
         "userId" to uid) 

     query.exec { 
      val rowParser = classParser<UserModel>() 
      parseSingle(rowParser) // this line that trigger error exception 
     } 
    } 

    return data 
} 

我試圖找到count功能queryrowParser變量,以檢查是否存在記錄與否,但無法找到它。

沙发
0
1

從維基頁面。 https://github.com/Kotlin/anko/wiki/Anko-SQLite#parsing-query-results

解析查詢結果

因此,我們有一些光標,以及我們如何可以解析它變成普通班? Anko提供的函數parseSingle,parseOpt和parseList可以更簡單地完成它。

方法描述 parseSingle(rowParser):T解析一行 parseOpt(rowParser):T?解析零行或一行 parseList(rowParser):List解析零行或多行 請注意,如果接收的遊標包含多行,則parseSingle()和parseOpt()將引發異常。

+0

哦,我以爲parseSingle也接受空記錄。好吧,我要用parseList來試試它。 – Kakashi

+0

它的工作原理,謝謝! – Kakashi

0
votes
answers
41 views
+10

在Xamarin中使用SQLite數據庫的C#類中的另一個泛型中使用泛型類型

1

我有一個簡單的數據庫控制處理程序類。使用SQLiteConnection。我有我的SQLite數據庫中的幾個表。在Xamarin中使用SQLite數據庫的C#類中的另一個泛型中使用泛型類型

現在我想爲所有使用int Id作爲主鍵的特定類型的表編寫一個通用的簡單訪問器函數。因此,我有一個基類TableWithIntId,它總是有一個int Id作爲主鍵。

我的簡化代碼:

private SQLiteConnection sqliteConnection; 

public T LoadRecord<T>(int id) where T : Database.TableWithIntId 
{ 
    try 
    { 
     return (from objTable in sqliteConnection.Table<T>() 
      where objTable.Id == id 
      select objTable).First(); 
    } 
    catch (Exception ex) 
    { 
     ErrorMessage = ex.Message; 
     return null; 
    } 
} 

的問題是,我得到了以下錯誤:

錯誤CS0310:「T」必須是一個非抽象類有一個公共的無參數的構造函數爲了在通用類型或方法'SQLiteConnection.Table()'中使用它作爲參數'T'

這對我來說很困惑,因爲T是非抽象的並且具有自動的默認構造函數。

public class TableWithIntId 
{ 
    [PrimaryKey] 
    public int Id { get; set; } 
} 
+1

你需要在'指定'新的()''爲約束T'條款where'。 –

沙发
0
3

約束where T : Database.TableWithIntId只是說T必須從Database.TableWithIntId派生。但派生類不一定有無參數的構造函數(如果你只給它們帶參數的構造函數)。

添加new()約束來解決:

public T LoadRecord<T>(int id) where T : Database.TableWithIntId, new() 

制約T將類與參數構造函數。

+0

完美!因爲你是第一個我接受這個! – xMRi

板凳
0
1

看看new Constraint (C# Reference)

public T LoadRecord<T>(int id) where T : TableWithIntId, new() 
    { 
     try 
     { 
      return (from objTable in sqliteConnection.Table<T>() 
        where objTable.Id == id 
        select objTable).First(); 
     } 
     catch (Exception ex) 
     { 
      ErrorMessage = ex.Message; 
      return null; 
     } 
    }