Managing SQLite Database for Windows Store Apps using C# - c#

I am using SQLite database for my Windows Store app. I completed my requirement of usage of Database with the help of MSFT samples & Blogs. Now I want to Change/Update the Data which is in the Database File..
My Insert code like this..
using (var db = new SQLite.SQLiteConnection(dbpath))
{
db.Insert(new ItemEpub.EpubBookList()
{
BookName = file.DisplayName,
BookPath = file.Path,
}
);
db.Commit();
db.Dispose();
db.Close();
}
I didn't get the Syntax & any simple information about Update the Database table.
Right now my code is:
StorageFile DataFile = await ApplicationData.Current.LocalFolder.GetFileAsync("Epub.db3");
using (var db = new SQLite.SQLiteConnection(dbpath))
{
db.Update EpubBookList Set
string sql = UPDATE EpubBookList SET LastVisitedPage = '" + lastVisistedPageIndex + "',";
db.Dispose();
db.Close();
}
May be this code looks like ugly, Apart from this code give me any Suggestion on Update the Exiting row in metro apps

To update the existing record, first you need to get that object via SQL query [Query<T>(...)] or Get<T>(...) method. Then update the object properties and call Update(...) method.
using (var db = new SQLite.SQLiteConnection(dbpath))
{
var objPerson = db.Query<Person>("select * from dbPerson where PersonId = ?", 9);
/*** or ***/
var objPerson = db.Get<Person>(9); // Here 9 is primary key value
/*** update the object ***/
objPerson.FirstName = "Matt";
db.Update(objPerson);
}
You don't need to call db.Dispose(); & db.Close(); because you are using using.

Related

Database Sync - Local and Online without Replication

So I have this code that checks if new data is added to online database by comparing the rows of online and local database. If new data is found it inserts the new data to local database.
public class Reservation
{
public string res_no { get; set; }
public string mem_fname { get; set; }
}
My Code :
private async void updateDineList()
{
DBconnector.OpenConnection();
//Gets data from online database
HttpClient client = new HttpClient();
var response = await client.GetStringAsync("http://example.com/Reservation/view_pending_reservation");
var persons = JsonConvert.DeserializeObject<List<Reservation>>(response);
//Gets data from Local database
string string_reservation = "SELECT res_no,mem_fname FROM res_no WHERE res_status='pending';";
DataTable reservation_table = new DataTable();
MySqlDataAdapter adapter_reservartion = new MySqlDataAdapter(string_reservation, DBconnector.Connection);
adapter_reservartion.Fill(reservation_table);
//Gets the row of each table
int local = reservation_table.Rows.Count;
int online = persons.Count;
//Compares rows of online and local database
if (local < online)
{
//if the rows of online database is greater than local database
//inserts the new data from local database
string Command_membership = "INSERT INTO reservation_details (res_no,mem_fname) VALUES (#res_no, #mem_fname);";
for (int i = local; i < online; i++)
{
//inserts new data from online to local database
using (MySqlCommand myCmd = new MySqlCommand(Command_membership, DBconnector.Connection))
{
myCmd.CommandType = CommandType.Text;
myCmd.Parameters.AddWithValue("#res_no", persons[i].res_no);
myCmd.Parameters.AddWithValue("#mem_fname", persons[i].mem_fname);
myCmd.ExecuteNonQuery();
}
}
MessageBox.Show("New Records Found");
}
else
{
MessageBox.Show("No new Records");
}
DBconnector.Connection.Close();
}
So my question is there any problem could occur with this code, it works fine but is there any way to improve this. I know MySQL replication is better but I am only using free Web Hosting with few MySQL privileges.
The clear improvement is not to create a new command for every row. You should either create the command and parameters once and then set the parameters and call for each row, or better still package the set of updates into a single structure, like and xml string, and then pass the whole lot to the database via a stored procedure call.
Other probably problematic issue is that you are checking purely based on row counts. Don't know if that is valid in your scenario but it sounds dangerous. What if rows are deleted? or is that not possible in your scenario. Some other way of checking last updates would probably be preferable.
Without more context that's about all I can see.

how to sync with filter data using Microsoft Sync Framework

I am woking on Microsoft Sync Framework with sql server 2008 and c# below is my code
public static void SetUp(string _pScopeName, DbSyncTableDescription _pDbSyncTable, SqlConnection serverConn, SqlConnection clientConn)
{
// Create a scope named "_ITEM" and add tables to it.
DbSyncScopeDescription productScope = new DbSyncScopeDescription(_pScopeName);
// Define the Products table.
// Add the Table to the scope object.
productScope.Tables.Add(_pDbSyncTable);
// Create a provisioning object for "_ITEM" and apply it to the on-premise database if one does not exist.
SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, productScope);
serverProvision.ObjectSchema = ".dbo";
string _tblName = _pDbSyncTable.LocalName.Replace("[", "").Replace("]", "");
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
serverProvision.Tables[_tblName].AddFilterColumn("_WORKGROUPNAME");
serverProvision.Tables[_pDbSyncTable.LocalName].FilterClause = "[" + _tblName + "].[_WORKGROUPNAME] = " + _CCompanyVar._WORKGROUPNAME;
//Skip create Sync Framework objects because we have already created them on the previous step
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
//Create new select changes procedure for our scope
serverProvision.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);
if (_CPubVar._Stop_bool)
{
return;
}
if (!serverProvision.ScopeExists(_pScopeName))
serverProvision.Apply();
// Provision the SQL client database from the on-premise SQL Server database if one does not exist.
SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConn, productScope);
if (_CPubVar._Stop_bool)
{
return;
}
if (!clientProvision.ScopeExists(_pScopeName))
clientProvision.Apply();
}
i am getting Error :
The multi-part identifier "_ATTENDANCESTATUS._WORKGROUPNAME" could not be bound.
Invalid column name 'FPR'.
at line :
serverProvision.Apply();
if i remove below lines my Sync process work correctly without filter
string _tblName = _pDbSyncTable.LocalName.Replace("[", "").Replace("]", "");
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
serverProvision.Tables[_tblName].AddFilterColumn("_WORKGROUPNAME");
serverProvision.Tables[_pDbSyncTable.LocalName].FilterClause = "[" + _tblName + "].[_WORKGROUPNAME] = " + _CCompanyVar._WORKGROUPNAME;
//Skip create Sync Framework objects because we have already created them on the previous step
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
//Create new select changes procedure for our scope
serverProvision.SetCreateProceduresForAdditionalScopeDefault(DbSyncCreationOption.Create);
_WORKGROUPNAME is a common field in my all tables and I want to filter data on _WORKGROUPNAME which i pass value in _CCompanyVar._WORKGROUPNAME (string variable)...
where I am wrong please point out ...
use this ...
public static void SetUp(string _pScopeName, DbSyncTableDescription _pDbSyncTable, SqlConnection serverConn, SqlConnection clientConn)
{
// Create a scope named "_ITEM" and add tables to it.
DbSyncScopeDescription productScope = new DbSyncScopeDescription(_pScopeName);
// Define the Products table.
// Add the Table to the scope object.
Collection<string> includeColumns = new Collection<string>();
for (int i = 0; i < _pDbSyncTable.Columns.Count; i++)
{
includeColumns.Add(_pDbSyncTable.Columns[i].UnquotedName);
}
DbSyncTableDescription productDescription = SqlSyncDescriptionBuilder.GetDescriptionForTable(_pScopeName, includeColumns, serverConn);
productScope.Tables.Add(productDescription);
// Create a provisioning object for "_ITEM" and apply it to the on-premise database if one does not exist.
SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, productScope);
serverProvision.ObjectSchema = ".dbo";
// Filter Rows for the ListPrice column
serverProvision.Tables[ _pDbSyncTable.LocalName].AddFilterColumn("_WORKGROUPNAME");
serverProvision.Tables[ _pDbSyncTable.LocalName].FilterClause = "[side].[_WORKGROUPNAME] = '" + _CCompanyVar._WORKGROUPNAME + "'";
if (_CPubVar._Stop_bool)
{
return;
}
if (!serverProvision.ScopeExists(_pScopeName))
serverProvision.Apply();
// Provision the SQL client database from the on-premise SQL Server database if one does not exist.
SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConn, productScope);
if (_CPubVar._Stop_bool)
{
return;
}
if (!clientProvision.ScopeExists(_pScopeName))
clientProvision.Apply();
}

changing the sourcetable of a linked table in access 2007 with C#

I'll start by asking am I right in thinking that in the image below:
the 'TABLE=CLOASEUCDBA.T_BASIC_POLICY' is not part of the connection string? in fact it is the source table name?
I'm looking to alter this to another linked table on the same database. The connection string should there be the same and the name that appears in ACCESS should be the same. The only difference should be under the hood it is actually referencing another table and of course if you open the table it will contain different fields and data.
my code for far to do this is:
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\xxxx\Documents\Test.accdb");
foreach (TableDef tbd in db.TableDefs)
{
if (tbd.Name.Contains("CLOASEUCDBA_T_BASIC_POLICY"))
{
tbd.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
}
}
db.Close();
However I'm getting a big fat COMException "Cannot set this property once the object is part of a collection.". I'm not sure exactly why and all the examples I can find online are all written in VB/VBA and I only have very very limited exposure to this. Any help is appreciated.
EDIT:
I have tried to go a different route with no futher success using the code:
if (tbd.Name.Contains("CLOASEUCDBA_T_BASIC_POLICY"))
{
var newtable = db.CreateTableDef("this is a new table");
newtable.Name = "new table";
newtable.Connect = tbd.Connect;
newtable.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
db.TableDefs.Append(newtable);
//tbd.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
}
In this case I get the error "ODBC--call failed."
Since we're not allowed to change the SourceTableName of a TableDef object that already exists in the TableDefs collection we need to create a new TableDef object, .Delete the old one, and then .Append the new one:
// This code requires the following COM reference in your project:
//
// Microsoft Office 14.0 Access Database Engine Object Library
//
// and the declaration
//
// using Microsoft.Office.Interop.Access.Dao;
//
// at the top of the class file
string tableDefName = "CLOASEUCDBA_T_BASIC_POLICY";
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(#"C:\Users\xxxx\Documents\Test.accdb");
var tbdOld = db.TableDefs[tableDefName];
var tbdNew = db.CreateTableDef(tableDefName);
tbdNew.Connect = tbdOld.Connect;
tbdNew.SourceTableName = "CLOASEUCDBA_T_BILLING_INFORMATION";
db.TableDefs.Delete(tableDefName); // remove the old TableDef ...
db.TableDefs.Append(tbdNew); // ... and append the new one
db.Close();

Nhibernate transaction locks a tabel

I have developed a WCF api which is using nHibernate. I am new to this. I have used session.update to take care of transaction. I have a for loop in which based on select condition I am updating a record ie. If A is present in tabel1 then I am updating the table else inserting a new entry.
I am getting "could not execute query." when trying to execute a select query on a table which was previously being updated by adding a new entry in the table.
What I think is, because I am using session.save(table1) and then trying select entries from that table I am getting an error. Since session.save temporarily locks the table I am not able to execute a select query on that table.
What can be the solution on this?
Update:
This the for loop I am using to check in the database for some field:
using (ITransaction tranx = session.BeginTransaction())
{
savefunction();
tranx.Commit();
}
Save function:
public void savefunction()
{
for (int i = 0; i < dictionary.Count; i++)
{
ICandidateAttachmentManager candidateAttach = new ManagerFactory().GetCandidateAttachmentManager();
CandidateAttachment attach = new CandidateAttachment();
attach = checkCV();
if(attach == null)
{
//insert new entry into table attach
session.save(attach);
}
}
}
checkCV function:
public void checkCV()
{
using (ICandidateAttachmentManager CandidateAttachmentManager = new ManagerFactory().GetCandidateAttachmentManager())
{
IList<CandidateAttachment> lstCandidateAttachment = CandidateAttachmentManager.GetByfkCandidateId(CandidateId);
if (lstCandidateAttachment.Count > 0)
{
CandidateAttachment attach = lstCandidateAttachment.Where(x => x.CandidateAttachementType.Id.Equals(FileType)).FirstOrDefault();
if (attach != null)
{
return null;
}
else
{
return "some string";
}
}
}
}
What happening here is in the for loop if say for i=2 the attach value comes to null that I am entering new entry into attach table. Then for i=3 when it enters checkCV function I get an error at this line:
IList lstCandidateAttachment =
CandidateAttachmentManager.GetByfkCandidateId(CandidateId);
I think it is because since I am using session.save and then trying to read the tabel contents I am unable to execute the query and table is locked till I commit my session. Between the beginTransaction and commit, the table associated with the object is locked. How can I achieve this? Any Ideas?
Update:
I read up on some of the post. It looks like I need to set isolation level for the transaction. But even after adding it doesn't seem to work. Here is how I tried to inplement it:
using (ITransaction tranx = session.BeginTransaction(IsolationLevel.ReadUncommitted))
{
saveDocument();
}
something I don't understand in your code is where you get your nHibernate session.
Indeed you use
new ManagerFactory().GetCandidateAttachmentManager();
and
using (ICandidateAttachmentManager CandidateAttachmentManager = new ManagerFactory().GetCandidateAttachmentManager())
so your ManagerFactory class provides you the ISession ?
then you do:
CandidateAttachment attach = new CandidateAttachment();
attach = checkCV();
but
checkCV() returns either a null or a string ?
Finally you should never do
Save()
but instead
SaveOrUpdate()
Hope that helps you resolving your issue.
Feel free to give more details

unable to update values in SQLite DB after importing- windows phone

I followed this tutorial to import my existing database http://wp.qmatteoq.com/import-an-already-existing-sqlite-database-in-a-windows-8-application/ After copying my DB to project files and setting build action as content,I am copying the database to isolated storage.Now when I try to update a value in the database,and view the change in my binded list box, Im not able to see the changes.When I use isolated storage explorer and view the DB,the values have changed in DB.But querying it doesnt return me the updated values.I am using the same connection string in both cases.
//copy DB from installation folder to isolated storage
private async Task CopyDatabase()
{
bool isDatabaseExisting = false;
try
{
StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("sample.db");
isDatabaseExisting = true;
}
catch
{
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("sample.db");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
}
}
//update the value
dbConn = new SQLiteConnection(DB_PATH);
dbConn.Query<resources>(" update resources SET isFavorite = 'True' WHERE resourceId =" + rid);
}
// Query database to populate list box
string DB_PATH = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sample.db");
private SQLiteConnection dbConn;
dbConn = new SQLiteConnection(DB_PATH);
List<resources> retrievedpdf = dbConn.Query<resources>("select * from resources where categoryId=" + noid + " AND typeId=1" ).ToList<resources>();
pdflist.ItemsSource = retrievedpdf;
I am able to view changes in exploreer, but querying returns unmodified values.
I would like some changes in query that helps me a lot.
//Copy your database file From Installation folder to IsolatedStorage on App launching.
//Change your update query bu below query
int updateCount = dbConn.Execute("update resources SET isFavorite = 'True' WHERE resourceId =" + rid);
//Change your select Query
**Edits**
List<resources> retrievedpdf = dbConn.Table<resources>().ToList().Where(x=>x.categoryId.Equals(noid) && x.typeId.Equals(1)).ToList();
//Assign ListBox ItemSource to null before assign actual source
pdflist.ItemsSource = null;
pdflist.ItemsSource = retrievedpdf;
There was a problem with the query , I had been updating string "true" to a bool in a table..This is the correct query int updateCount = dbConn.Execute("update resources SET isFavorite = 1,modifiedTime = DATETIME('now') WHERE resourceId =" + rid);

Categories

Resources