I've attached an SQLite database to my Windows Phone 8.1 project. The connection is working but the results returned from the database are null.
Previously I posted a question on the null bindings of my query. But the answer suggested hasn't resolved the issue of a null result being returned, which is why I'm re-posting the question.
Debugging: Stepping through the SQLlite class I can see that the bindings are null although I don't see any reason for that considering the types in my DB schema and the associated field mappings in ZoneInfo.cs.
I query the database as follows which should map each field to my class ZoneInfo below.
using (var dbConn = new SQLiteConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, AppDBPath), true))
{
List<ZoneInfo> zoneInfo = dbConn.Query<ZoneInfo>("select * from " + tableName).ToList<ZoneInfo>();
ObservableCollection<ZoneInfo> zoneInfoCollection = new ObservableCollection<ZoneInfo>(zoneInfo);
return zoneInfoCollection;
}
Question:
How can I correct my database mappings so that the query result isn't empty?
**ZoneInfo.cs (mapping class for DB fields)**
public class ZoneInfo
{
//The ObjectId property is marked as the Primary Key
[SQLite.PrimaryKey]
[Column("objectId")]
public string ObjectId { get; set; }
[Column("zone")]
public string ZoneName { get; set; }
[Column("tariff_ph")]
public float TariffPH { get; set; }
[Column("tariff_pd")]
public float TariffPD { get; set; }
[Column("restrictions")]
public string Restrictions { get; set; }
[Column("days_of_operation")]
public string DaysOpen { get; set; }
[Column("hours_of_operation")]
public string HoursOpen { get; set; }
public ZoneInfo()
{
}
public ZoneInfo(string objectId, string zoneName, int tariffPH, int tariffPD,
string restrictions, string daysOpen, string hoursOpen )
{
ObjectId = objectId;
ZoneName = zoneName;
TariffPH = tariffPH;
TariffPD = tariffPD;
Restrictions = restrictions;
DaysOpen = daysOpen;
HoursOpen = hoursOpen;
}
}
Query Result: (You can see that the result of the query's field's are all null which isn't the case in the database:
The DB schema is as follows and this is a link to the DB file for testing:
The schema error causing the null mapping bindings, was the result of stale SQLLite database being referenced on the device.
Deleting the app from the phone and rebuilding the app via Visual Studio caused the database to be redeployed to the file system with the updated correct mappings. :)
1.From the Start screen, swipe left to display the Apps list. Alternatively from the Start screen, tap the right arrow (located in the lower-right).
2.Touch and hold an app.
3.Tap uninstall.
4.Tap yes.
Related
I am new to Xamarin and SQLite so I'm asking myself what is a good practise to keep the database structure up to date, when a new column is added or so. To use the SQLite DB I am using SQLite-net-pcl.
I have read about some solutions that use a version field stored somewhere and that is used to alter the database structure manually when the version changes.
But from what I saw is that calling CreateTable on a SQLiteConnection does not only create the table, it also updates the table in the database when the underlying class changes.
So, is it a good practise just to call
SQLiteConnection db = new SQLiteConnection(dbPath);
db.CreateTable<ClassA>();
everytime the system initializes, to keep the database up to date? Every change to ClassA will then be applied to the database table without any data loss.
I test this operation, I got the following result.
First of all, My model like following code.
public class Prijem
{
[PrimaryKey, AutoIncrement, Unique]
public int BCode { get; set; }
public string Name { get; set; }
public string FirmName { get; set; }
public string ItemCode { get; set; }
public string Count { get; set; }
}
I use following code to insert data.
await App.Pdatabase.SavePrijemAsync(new Prijem() {Name="New",FirmName="55Fame" ,ItemCode="dg",Count="15"});
My SavePrijemAsync method like following code.
public Task<int> SavePrijemAsync(Prijem prijem)
{
if (IsExisted(prijem))
{
return _database.UpdateAsync(prijem);
}
else
{
return _database.InsertAsync(prijem);
}
}
I got the record like following sceenshot in the sqlite database.
Then I just add a property called MyImage
public class Prijem
{
[PrimaryKey, AutoIncrement, Unique]
public int BCode { get; set; }
public string Name { get; set; }
public string FirmName { get; set; }
public string ItemCode { get; set; }
public string Count { get; set; }
string image = " Image";
public string MyImage
{
set
{
if (image != value)
{
image = value;
}
}
get
{
return image;
}
}
}
I used update operation like following code.
await App.Pdatabase.SavePrijemAsync(new Prijem() {Name="New",FirmName="55Fame" ,ItemCode="dg",Count="15" });
And insert operation like following code.
await App.Pdatabase.SavePrijemAsync(new Prijem() { Name = "New11", FirmName = "55Fame", ItemCode = "dg", Count = "15" });
I got the result in the database like following screenshot.
In the end, We can get the result, If we add a property to the Model. this column will be added in the sqlite database, but default value we must update it manually for existing data, if we insert the new value to the database, the default value will be added.
I'm creating Windows 10 Store application and I have a problem when calling PullAsync method. I was using Azure Mobile App for a long time and I always used private IMobileServiceTable<MyTable> table. Now, I need to add support of something in Microsoft called Offline Sync. Following instruction, I didn't succeeded.
Here's my code.
using Microsoft.WindowsAzure.MobileServices;
using Microsoft.WindowsAzure.MobileServices.Sync;
using Microsoft.WindowsAzure.MobileServices.SQLiteStore;
private IMobileServiceSyncTable<MyTable> OffTable = App.MobileService.GetSyncTable<MyTable>();
private IMobileServiceTable<MyTable> OnTable = App.MobileService.GetTable<MyTable>();
protected ovveride async OnNavigatedTo()
{
if(!App.MobileService.SyncContext.IsInitialized)
{
var store = new MobileServiceSQLiteStore("localstore.db");
store.DefineTable<MyTable>();
await App.MobileService.SyncContext.InitializeAsync(store);
}
await OffTable.PullAsync("uniqueID", OffTable.CreateQuery());
var data = await OffTable.ToCollectionAsync(); //return -> nothing
var data2 = await OnTable.ToCollectionAsync(); //return -> 50 rows
}
And MyTable.cs
using Microsoft.WindowsAzure.MobileServices;
using Newtosoft.Json;
[DataTable("MyTable")]
public sealed class MyTable
{
[JsonProperty]
public int ID { get; set;}
[JsonProperty]
public string Field1 { get; set; }
//...
[JsonProperty(PropertyName = "version")]
[Version]
public string Version { get; set; }
[JsonProperty(PropertyName = "deleted")]
[Deleted]
public bool Deleted { get; set; }
[JsonProperty(PropertyName = "updatedAt")]
[UpdatedAt]
public DateTime UpdatedAt { get; set; }
[JsonProperty(PropertyName = "createdAt")]
[CreatedAt]
public DateTime CreatedAt { get; set; }
}
Here's values from project.json:
"Microsoft.Azure.Mobile.Client": "2.0.1",
"Microsoft.Azure.Mobile.Client.SQLiteStore": "2.0.1"
What I'm doing wrong?
Problem was on the server side.
So, basically you need to create Table via Azure Portal. You can create via SQL Management Studio as well, but when creating via Portal, you will have createdAt, updatedAt, version and deleted in right format. So, if you created table via SQL MGMNT Studio, go to Portal and click Create Table, enter your table's name. It's OK, your data WILL NOT be overwritten and then everything should work fine.
I'm using the SQLite libs and SQLite.Net to query an existing database in my Windows Phone 8.1 project. So far the connection to the db is executing fine but the records being returned are null.
I took the usual debugging steps -
1.Checked the binding types and names which map to the names in my db schema.
2.Verified the data exists in the DB.
3.Stepped through the code that queries the database, found that the db bindings are null. (This suggests to me an issue with the field mappings in my POCO)
I don't get any compile time error as such but the records being returned are null.
Question:
Does anyone know why there is an issue with the bindings provided for the database mapping?
When I stepped through the SQLite.cs class I found the binding count is 0:
Query Code:
using (var dbConn = new SQLiteConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, AppDBPath), true))
{
List<ZoneInfo> zoneInfo = dbConn.Query<ZoneInfo>("select * from " + tableName).ToList<ZoneInfo>();
ObservableCollection<ZoneInfo> zoneInfoCollection = new ObservableCollection<ZoneInfo>(zoneInfo);
return zoneInfoCollection;
}
DB Mapping POCO:
public class ZoneInfo
{
//The ObjectId property is marked as the Primary Key
[SQLite.PrimaryKey]
[Column("objectId")]
public string ObjectId { get; set; }
[Column("zone")]
public string ZoneName { get; set; }
[Column("tariff_ph")]
public int? TariffPH { get; set; }
[Column("tariff_pd")]
public int? TariffPD { get; set; }
[Column("restrictions")]
public string Restrictions { get; set; }
[Column("days_of_operation")]
public string DaysOpen { get; set; }
[Column("hours_of_operation")]
public string HoursOpen { get; set; }
public ZoneInfo()
{
}
public ZoneInfo(string objectId, string zoneName, int tariffPH, int tariffPD,
string restrictions, string daysOpen, string hoursOpen )
{
ObjectId = objectId;
ZoneName = zoneName;
TariffPH = tariffPH;
TariffPD = tariffPD;
Restrictions = restrictions;
DaysOpen = daysOpen;
HoursOpen = hoursOpen;
}
}
Database schema -
Your "DB Mapping POCO" does not match your Database schema.
[Column("tariff_ph")]
public int? TariffPH { get; set; }
[Column("tariff_pd")]
public int? TariffPD { get; set; }
Should probably be
[Column("tariff_ph")]
public float TariffPH { get; set; }
[Column("tariff_pd")]
public int TariffPD { get; set; }
Since you have floating point values in your dataset and both of them are NOT NULLABLE.
I have an minimum example here Update Record in Sqlite Window Phone 8, that creates the database, inserts some data and updates the database. See if that can help you, but I'm pretty sure your data doesn't match correctly.
We need to change one of our tables to use a Guid as the primary key rather than an int. This system is in use in production and it appears that this change requires some additional work rather than the usual add-migration stuff.
There are two FK references to this table meaning that there are 3 total tables needing to be modified.
How should this be handled when using Code First?
CURRENT MODEL CODE
public class TableA
{
public int Id { get; set; }
public String Name { get; set; }
public bool IsActive { get; set; }
}
DESIRED MODEL CODE
public class TableA
{
public Guid Id { get; set; }
public String Name { get; set; }
public bool IsActive { get; set; }
}
First do the change on the code and then install or host your application and create the fresh database out of the new changes. Now you have the database with the new changes. So make a diff between the one in production ( after backing it up and import it in your test server) and the fresh one ( with the new change), now you can create your upgrade script from the diff for the production. Then first upgrade the database of production and then publish your app
I currently have an Entity Framework model that collects data from a legacy database and I am currently using an int on my Id properties
I am attempting to build a search box with autocomplete capabilities and want to have the autocomplete function to return a subset of records based on whether the sample id either contains or starts with (final design decision not made yet) and I am running into problems with converting the integer id to a string as I would normally use a recs.Id.toString().StartsWith(recordId) but this is apparently not supported by the Entity Framework
Is there a way around this limitation ?
My code looks like the following
Model:
public class Sample
{
public Sample()
{
Tests = new List<Test>();
}
public int Id { get; set; }
public DateTime SampleDate { get; set; }
public string Container { get; set; }
public string Product { get; set; }
public string Name { get; set; }
public string Status { get; set; }
public virtual SamplePoint SamplingPoint { get; set; }
public virtual SampleTemplate SampleTemplate { get; set; }
public Customer ForCustomer { get; set; }
public virtual ICollection<Test> Tests { get; set; }
}
and the query I am currently trying to apply to this model
[HttpGet]
public JsonResult AutoComplete(string partialId)
{
var filteredSamples =
repo.AllSamples.Where( s =>
String.Compare(s.Status, "A", false) == 0
&& (s.Id.ToString()).StartsWith(partialId)
).ToList();
return Json(filteredSamples, JsonRequestBehavior.AllowGet);
}
Any ideas would be awesome I am out of ideas at this point
No matter what you do, this is going to result in some awful performance on large datasets, because you will not be able to use any indices. My recommendation would be to use a trigger or scheduled task to store the leading digit in a separate field and filter on that.
I ended up adding a view for autocomplete data and converting the data to string in the select statement and this solved my issue
Wild thought: how about your create a computed, persisted column on your database table, that converts your ID (INT) into a string?
Then you could:
put an index on that column
use a simple string comparison on that string column
Basically, you need this:
ALTER TABLE dbo.YourTable
ADD IDAsText AS CAST(ID AS VARCHAR(10)) PERSISTED
Now update you EF model - and now you should have a new string field IDAsText in your object class. Try to run your autocomplete comparisons against that string field.