Xamarin.Fomrs SQLite DateTime not inserted properly through Query - c#

In my Xamarin.Forms app, I am generating queries at api side and I directly want to execute it in my local db.
I have a table like this.
[Table("TblUnit")]
public class TblUnit
{
[AutoIncrement, PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsFavourite { get; set; }
public int WebId { get; set; }
public int CompanyId { get; set; }
public DateTime OpeningStockDate { get; set; }
}
When I try to add object using InsertAsync(object) method, object is inserted with proper date. But when I try to fire query, date is not added to database. After firing query when I try to fetch data from this table OpeningStockDate comes as 01/01/0001.
//this is generated at api side and I directly want to fire query in my local sqlite db
var query = "insert into [TblUnit] (Name,Description,IsFavourite,WebId,CompanyId,OpeningStockDate) values('Bag','Description',true,12,185,'2021-03-04 10:00:00')";
I tried changing date format to mm/dd/yyyy as well. But no success.
I tried setting storeDateTimeAsTicks flag to false.
static readonly Lazy<SQLiteAsyncConnection> lazyInitializer = new Lazy<SQLiteAsyncConnection>(() =>
{
return new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags,false);
});
But then my entire app starts behaving incorrect. I can not get data from this table. It shows datetime parsing exception. Also can not add data to the table using InsertAsync method.
What I am doing wrong here ? Please tell me.
Thanks

Related

Server with different format date time from client - recursively change format date time client

I have a server with a different datetime format from my client. In my client its using PM / AM and my server is using format 24H. When I try using a DateTime variable in C# and datatype DateTime in my SQL Server. In my SQL Server 2020-06-16 14:54:33.937 When I try run in server PC its OK. but when I try run in client my date in SQL Server it returns int32 (different format).
I use dapper for SQL Server helper. This is my function to select my table
private static void get_chat()
{
ConnectDB();
string sql = "SELECT * FROM chat where to_user = " + MyLogin.id + " OR from_user = " + MyLogin.id;
var queryResult = cnn.Query<SQLServer_Chat>(sql);
SQLServer_Olah.Olah_Chat(queryResult);
ArrayList list_id = SQLServer_Olah.List_chat_id(queryResult);
CloseDB();
get_chat_det(list_id);
}
and this is my SQLServer_Chat
class SQLServer_Chat
{
public int id_chat { set; get; }
public int to_user { set; get; }
public int from_user { set; get; }
public string last_chat { set; get; }
public int to_unread { set; get; }
public int from_unread { set; get; }
public DateTime created_at { set; get; }
public DateTime last_chat_time { set; get; }
public string to_name { set; get; }
public string from_name { set; get; }
}
hope anyone can help me about this bug , thank you!!
Since you say the column is datetime in the database, frankly: format doesn't exist. I expect the problem is that you are saving it incorrectly, because you aren't using parameters. The query shown should really, really be:
var queryResult = cnn.Query<SQLServer_Chat>(
"SELECT * FROM chat where to_user = #id OR from_user = #id", new { MyLogin.id });
The anonymous type (new { ... }) tells Dapper to add a parameter called id with the type and value that it gets from evaluating MyLogin.id.
If we assume that your save code also didn't use parameters: then - the data in the database is now simply incorrect. The solution: use parameters; this fixes:
SQL injection problems (security)
culture (i18n/l10n) problems such as formatting (correctness)
database query plan reuse (performance)
dapper strategy reuse (performance)

Is calling 'Create Table' to keep database up to date a good practise?

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.

select query to get all values based on distinct values using linq

I have n number of services and under each service there will be 2 routes(some times more than 2). Under each route there are n number of stops. I am getting values from db as a table in below column order
ServiceId, Service Name,serviceLine color,RouteId, Route Name, Stop Id, Stop Name, Latitude, Longitude.
I want to convert it an object list of below format
public class Service
{
public string ServiceId { get; set; }
public string ServiceName { get; set; }
public string ServiceLineColor { get; set; }
public List<RouteData> RouteList { get; set; }
}
public class RouteData
{
public string RouteId { get; set; }
public string RouteCode { get; set; }
public string RouteName { get; set; }
public List<StopData> stopList { get; set; }
}
public class StopData
{
public string StopCode { get; set; }
public string StopName { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string StopType { get; set; }
}
Is there any easy way in linq to convert data in to below format? I wanted to avoid looping.. since i am getting nearly 1k records from db. Please help me to solve this issue.
Or is it best to use db calls to format data. i didn't prefer that because if there is 50 services i need to do 50 db calls and again have to do data formatting logic.
To avoid looping over the data structure each time, you could build up additional dictionaries that provide fast access of the objects by id:
var myServiceIndex = new Dictionary<string, Service>()
var myRouteDataIndex = new Dictionary<string, RouteData>()
Service service;
RouteData routData;
foreach (var record in databaseRecords)
{
if (myRouteDataIndex.TryGetValue(record.RouteId, out route))
{
// add stop data
}
else if (myServiceIndex.TryGetValue(record.ServiceId, out service)
{
// add route data
// add stop data
}
else
{
// add service
// add route data
// add stop data
}
}
You have a number of stops, and for each stop entry in database you have to map it to a C# object. In this case, looping is inevitable, as far as I see. Linq, and eg. entity framework, use looping internally.
One option is to use entity framework or Linq to SQL. It will give you strong type classes representing each DB table. But you have to change your DB schema and use foreign keys to link service, route, and stops.
C# code would look exactly like yours, which is auto generated by entity framework and in-sync with DB schema.
Second option is to convert manually. Note, your current schema doesn't complient with Third normal form. If you don't want to change your schema, you could read and generate them using group by clause.

How to resolve null bindings on SQLite query?

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.

search for int id starting with x entity framework 4.1

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.

Categories

Resources