SQLite query failing but only when offline - c#

I have a simple SQLite method which returns a class given two parameters - the type T and the parameter value to be searched
public T GetSingleObject<T>(string id) where T:IIdentity, new()
{
lock (dbLock)
{
using (var sqlCon = new SQLiteConnection(DBPath))
{
sqlCon.Execute(Constants.DBClauseSyncOff);
sqlCon.BeginTransaction();
string sql = string.Format("SELECT * FROM {0} WHERE id=\"{1}\"", GetName(typeof(T).ToString()), id);
var data = sqlCon.Query<T>(sql);
return data[0];
}
}
}
I also have another method that takes 3 parameters, T, the parameter to be seated and the value to search for
public T GetSingleObject<T>(string para, string val) where T:IIdentity, new()
{
lock (dbLock)
{
using (var sqlCon = new SQLiteConnection(DBPath))
{
sqlCon.Execute(Constants.DBClauseSyncOff);
sqlCon.BeginTransaction();
string sql = string.Format("SELECT * FROM {0} WHERE {1}=\"{2}\"", GetName(typeof(T).ToString()), para, val);
var data = sqlCon.Query<T>(sql).FirstOrDefault();
return data;
}
}
}
These methods work without an issue and return the values expected, but with one caveat - there is a single table which works fine when the phone has a connection, but not when it's in aeroplane mode. The table has nothing more in it than strings, doubles, ints, DateTime and bool values.
GetName is a simple method that removes the assembly bits and pieces and leave just the classname
private string GetName(string name)
{
var list = name.Split('.').ToList();
if (list.Count == 1)
return list[0];
var last = list[list.Count - 1];
return last;
}
I have tried every way I can think of to access this table - including a straight
sqlCon.ExecuteScalar<MyClass>("SELECT * FROM MyClass");
and nothing offline, perfect data online.
The class itself looks like this
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using SQLite;
namespace Models
{
public class MyClass : IIdentity
{
[PrimaryKey]
public string id { get; set; }
public string home_id { get; set; }
public string username { get; set; }
public string password { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public string email { get; set; }
public bool syncenabled { get; set; }
public string tradingname { get; set; }
public string address { get; set; }
public string town { get; set; }
public string state { get; set; }
public string country { get; set; }
public string securitystamp { get; set; }
public string password_question { get; set; }
public string password_answer { get; set; }
public string mobileServiceAuthenticationToken { get; set; }
public string providerUserKey { get; set; }
public string mobiledeviceid { get; set; }
public DateTime last_login { get; set; }
public DateTime __createdAt { get; set; }
public DateTime __updatedAt { get; set; }
public string user_type { get; set; }
public bool is_deleted { get; set; }
public bool account_enabled { get; set; }
public string subscription_id { get; set; }
[IgnoreDataMember, Ignore]
public List<MyUsers> UserModules { get { return AppDelegate.Self.DBManager.GetListOfObjects<MyUsers>("user_id", id); } }
public override string ToString()
{
return string.Format("[MyClasss: id={0}, home_id={1}, username={2}, password={3}, firstname={4}, lastname={5}, email={6}, syncenabled={7}, tradingname={8}, address={9}, town={10}, state={11}, country={12}, securitystamp={13}, password_question={14}, password_answer={15}, mobileServiceAuthenticationToken={16}, providerUserKey={17}, mobiledeviceid={18}, last_login={19}, __createdAt={20}, __updatedAt={21}, user_type={22}, is_deleted={23}, account_enabled={24}, subscription_id={25}, UserModules={26}]", id, home_id, username, password, firstname, lastname, email, syncenabled, tradingname, address, town, state, country, securitystamp, password_question, password_answer, mobileServiceAuthenticationToken, providerUserKey, mobiledeviceid, last_login, __createdAt, __updatedAt, user_type, is_deleted, account_enabled, subscription_id, UserModules);
}
}
Nothing in there that I can see should cause an issue when offline. The query always returns null offline, data online.

Related

Combining data from 2 databases in MVC

I am fairly new to asp.net mvc and I currently have an application that shows a number of errors. I have 2 pages that contain Application Errors and Log Errors. The data comes from 2 different databases but I am wanting to display the data from both databases on one page.
The tables have headings with different names that mean the same thing e.g. ApplicationName in the Application Database is the same thing as LogName in the Log Database.
Below is a small example of what I currently have and an example of what I am wanting.
Current
Application Errors
ID ApplicationName ApplicationMessage ApplicationDate
1 Something Hello World 01/01/2015
2 Something Else Another Message 03/01/2015
Log Errors
ID LogName LogMessage LogDate
1 Some Log A log message 02/01/2015
2 Another Log Another Log Message 04/01/2015
What I Want
Internal Errors
ID Name Message Date
1 Something Hello World 01/01/2015
2 Some Log A log message 02/01/2015
3 Something Else Another Message 03/01/2015
4 Another Log Another Log Message 04/01/2015
At the minute, I have 2 separate models for each database but I think I need to merge both models into one model that combines them both but I am unsure on how to do this. How would I be able to merge both data sources together to display the data within the same page?
Current Models
Application
[Table("ELMAH_Error")]
public class ElmahError
{
[Key]
public System.Guid ErrorId { get; set; }
public System.String Application { get; set; }
public System.String Host { get; set; }
public System.String Type { get; set; }
public System.String Source { get; set; }
public System.String Message { get; set; }
public System.String User { get; set; }
public System.Int32 StatusCode { get; set; }
public System.DateTime TimeUtc { get; set; }
public System.Int32 Sequence { get; set; }
public System.String AllXml { get; set; }
}
Log
[Table("LogEntry")]
public class LogEntry
{
[Key]
public Int64 ID { get; set; }
public DateTime LogDate { get; set; }
public Int16 Priority { get; set; }
public string SourceClass { get; set; }
public string Category { get; set; }
public string Message { get; set; }
public string UserID { get; set; }
public string ProcessID { get; set; }
}
From the models, there are a number of fields that I would like to merge as well as fields that are not similar that I would also like to include. The model below shows exactly what I want but I just don't know how to implement it.
Internal Errors
public class InternalErrors
{
public string Id { get; set; } //L:ID && E:ErrorId
public int Priority { get; set; } //L:Priority
public string Application { get; set; } //L:SourceClass && E:Application
public string Message { get; set; } //L:Message && E:Message
public string Type { get; set; } //L:Category && E:Type
public string User { get; set; } //L:UserID && E:User
public string ProcessID { get; set; } //L:ProcessID
public DateTime Date { get; set; } //L:LogDate && E:TimeUtc
public int StatusCode { get; set; } //E:StatusCode
public string AllXml { get; set; } //E:AllXml
public int Sequence { get; set; } //E:Sequence
public int ErrorCount { get; set; } //E:ErrorCount
}
I hope this is enough information for you to provide an answer, if you need anything else, let me know.
Thanks in advance
if what you want is this
Internal Errors
ID Name Message Date
1 Something Hello World 01/01/2015
2 Some Log A log message 02/01/2015
3 Something Else Another Message 03/01/2015
4 Another Log Another Log Message 04/01/2015
then create a class with name InternalErrors as follows.
public class InternalErrors
{
public int ID;
public string Name;
public string Message;
public DateTime Date;
}
Now you can write a Linq Query as follows to get data from Application Errors and Log Errors and Perform union on it.
var AppErrors=from AE in _db.ApplicationErrors select AE;
var LogErrors=from LE in _dc.LogErrors select LE;
var internerrors=AppErrors.Union(LogErrors);
var InternalErrors=(from ie in internerrors select new InternalErrors()
{
ID=ie.ID,
Message=ie.ApplicationMessage,
Name=ie.ApplicationName,
Date=ie.ApplicationDate
}).ToList();
The viewmodel approach from MRebati is the best solution.
I often find it usefull to have a base class and different implementations:
public abstract class ErrorViewModel
{
public abstract int Id { get; }
public abstract string Name { get; }
}
public class ElmahErrorViewModel
{
public ElmahErrorViewModel(ElmahError instance)
{
this.Instance = instance;
}
public ElmahError Instance { get; private set; }
public int Id { get { return Instance.ErrorId; } }
public string Name { get { return instance.Appication; } }
}
that way you can create a List<ErrorViewModel> and add entries with
var items = from e in context.ElmahErrors
select new ElmahErrorViewModel(e);
list.AddRange(items);
var items2 = from l in context.LogEntrys
select new LogEntryViewModel(l);
list.AddRange(items2);
This is very usefull since you hide the details but you still can seprate the list and access the underlying object with
var elmahErrors = items.OfType<ElmahErrorViewModel>().Select(x => x.Instance);
There are many ways to provide data from the models to the View.
One is the ViewModel. It must contain the data you want to send to view. Look at this:
using System;
public class ErrorViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public DateTime Date { get; set; }
}
And in the Controller you need to Create a list of this ViewModel and populate it with your data.
you can use linq
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var elmahErrorList = new List<ElmahError>{
new ElmahError{ ErrorId = Guid.NewGuid(), Application = "Something",Message = "Hello World" , TimeUtc = DateTime.Now },
new ElmahError{ ErrorId = Guid.NewGuid(), Application = "Something Else",Message = "Another Message" , TimeUtc = DateTime.Now }
};
var logEntryList = new List<LogEntry>{
new LogEntry{ ID = 1, SourceClass = "Something",Message = "Hello World" , LogDate = DateTime.Now },
new LogEntry{ ID = 1, SourceClass = "Something Else",Message = "Another Message" , LogDate = DateTime.Now }
};
var internalErrorsList = new List<InternalErrors>();
var elmahErrorListinternalErrorses = elmahErrorList.Select(e => new InternalErrors
{
Id = e.ErrorId.ToString(),
Application = e.Application,
Message = e.Message,
Type = e.Type,
User = e.User,
Date = e.TimeUtc,
StatusCode = e.StatusCode,
AllXml = e.AllXml,
Sequence = e.Sequence
});
internalErrorsList.AddRange(elmahErrorListinternalErrorses);
var elmahErrorListlogEntryLists = logEntryList.Select(l => new InternalErrors
{
Id = l.ID.ToString(),
Priority = l.Priority,
Application = l.SourceClass,
Message = l.Message,
Type = l.Category,
User = l.UserID,
Date = l.LogDate
});
internalErrorsList.AddRange(elmahErrorListlogEntryLists);
internalErrorsList.ForEach(f =>
{
Console.Write(f.Id); Console.Write("\t");
Console.Write(f.Application);Console.Write("\t");
Console.Write(f.Message);Console.Write("\t");
Console.Write(f.Date);Console.Write("\t");
Console.WriteLine();
});
}
public class InternalErrors
{
public string Id { get; set; } //L:ID && E:ErrorId
public int Priority { get; set; } //L:Priority
public string Application { get; set; } //L:SourceClass && E:Application
public string Message { get; set; } //L:Message && E:Message
public string Type { get; set; } //L:Category && E:Type
public string User { get; set; } //L:UserID && E:User
public string ProcessID { get; set; } //L:ProcessID
public DateTime Date { get; set; } //L:LogDate && E:TimeUtc
public int StatusCode { get; set; } //E:StatusCode
public string AllXml { get; set; } //E:AllXml
public int Sequence { get; set; } //E:Sequence
public int ErrorCount { get; set; } //E:ErrorCount
}
public class ElmahError
{
public System.Guid ErrorId { get; set; }
public System.String Application { get; set; }
public System.String Host { get; set; }
public System.String Type { get; set; }
public System.String Source { get; set; }
public System.String Message { get; set; }
public System.String User { get; set; }
public System.Int32 StatusCode { get; set; }
public System.DateTime TimeUtc { get; set; }
public System.Int32 Sequence { get; set; }
public System.String AllXml { get; set; }
}
public class LogEntry
{
public Int64 ID { get; set; }
public DateTime LogDate { get; set; }
public Int16 Priority { get; set; }
public string SourceClass { get; set; }
public string Category { get; set; }
public string Message { get; set; }
public string UserID { get; set; }
public string ProcessID { get; set; }
}
}
Demo : https://dotnetfiddle.net/mrWGDn

Mapping a list of objects within another object in SOQL using the Force.com Toolkit for .NET

I'm trying to query SalesForce using the Force.com Toolkit for .NET. After playing around with the example code I noticed you can map the result of a query to an object as so:
private class Account
{
public const String SObjectTypeName = "Account";
public String Id { get; set; }
public String Name { get; set; }
}
Where you can assign the query result as such:
var results = await client.QueryAsync<Account>(qry);
What I'm wondering about is how I map a Contacs object within the account object if I have something like this:
private class Account
{
public const String SObjectTypeName = "Account";
public String Id { get; set; }
public String Name { get; set; }
public List<Contact> contacs{get;set;}
}
private class Account
{
public const String SObjectTypeName = "Contacs";
public String Id { get; set; }
public String Name { get; set; }
}
And my query looks like this:
Select id,Name, (Select, id, name From Contacs) from Account
What I'm expecting is a list of contacts related to the Account object.
This should do the trick....
private class Account
{
public const String SObjectTypeName = "Account";
public String Id { get; set; }
public String Name { get; set; }
public ContactsResult Contacts { get; set; }
}
private class ContactsResult
{
public Contacts[] Records { get; set; }
}
private class Contacts
{
public String Id { get; set; }
public String Name { get; set; }
}
Additionally you can always cast the results to an object which will return the json result and you can use a tool such as http://json2csharp.com/ to create the model for you.

Entity Framework N- Layer no binding with datagridview

I have a layer of Data like this to bring me all Admins:
public List<Datos_Admin> SelectAllAdmin()
{
return (from u in contexto.Datos_Admin select u).ToList() ;
}
In my layer of Entities have this:
public class EDatos_Admin
{
public int Id_Admin { get; set; }
public string User_Name { get; set; }
public char Password { get; set; }
public string Nombre { get; set; }
public string Ap_Paterno { get; set; }
public string Ap_Materno { get; set; }
public DateTime Fecha_Alta { get; set; }
public DateTime Fecha_Modificacion { get; set; }
public int UserAdmin_Modificacion { get; set; }
public bool Activo { get; set; }
public EDatos_Admin(int Id_Admin, string User_Name, char Password, string Nombre, string Ap_Paterno, string Ap_Materno, DateTime Fecha_Alta, DateTime Fecha_Modificacion, int UserAdmin_Modificacion, bool Activo)
{
this.Id_Admin = Id_Admin;
this.User_Name = User_Name;
this.Password = Password;
this.Nombre = Nombre;
this.Ap_Paterno = Ap_Paterno;
this.Ap_Materno = Ap_Materno;
this.Fecha_Alta = Fecha_Alta;
this.Fecha_Modificacion = Fecha_Modificacion;
this.UserAdmin_Modificacion = UserAdmin_Modificacion;
this.Activo = Activo;
}
public EDatos_Admin()
{
// TODO: Complete member initialization
}
}
And in my Bussines layer have this:
public EDatos_Admin SeleccionaAllDatos_Admin()
{
foreach (var n in contexto.SelectAllAdmin())
{
listDatosAdmin = new EDatos_Admin()
{
Id_Admin = n.Id_Admin,
User_Name = n.User_Name,
};
}
return listDatosAdmin;
}
In the datagridview only I want show me Id_Admin and User_Name but it doesn't. And when I review in debugging I can see the data but the datagridview doesn't work.
And I call the method SeleccionaAllDatos_Admin in my Bussines layer like this in the load form
dataGridView1.DataSource = new NDatos_Admin().SeleccionaAllDatos_Admin();
How can fixed?
Thanks

Json.NET - Custom Converter - String To Int

I've got a problem regarding Json.NET and the omdbapi. I'm trying to retrieve information from the omdbapi and some properties are giving me headaches, particularly the "imdbVotes" one since it's written, in example, as "321,364" so I can't get an integer from it.
I'm betting that I need a custom converter, but I'm afraid that, at the moment, I don't really understand how to create one for my particular problem.
All other properties work well (I'm not using all of them at the moment).
This is the response for, lets say Snatch : http://www.omdbapi.com/?i=&t=snatch
This is my class :
public class MovieJSON
{
[JsonProperty(PropertyName = "Title")]
public String Title { get; set; }
[JsonProperty(PropertyName = "Year")]
public int Year { get; set; }
[JsonProperty(PropertyName = "Genre")]
public String Genre { get; set; }
[JsonProperty(PropertyName = "Director")]
public String Director { get; set; }
[JsonProperty(PropertyName = "Actors")]
public String Actors { get; set; }
[JsonProperty(PropertyName = "Plot")]
public String Plot { get; set; }
[JsonProperty(PropertyName = "Poster")]
public String Poster { get; set; }
[JsonProperty(PropertyName = "Metascore")]
public int Metascore { get; set; }
[JsonProperty(PropertyName = "imdbRating")]
public decimal ImdbRating { get; set; }
[JsonProperty(PropertyName = "imdbVotes")]
public int ImdbVotes { get; set; }
}
UPDATE #1 :
How can I handle the response when the property has the value "N/A"?. That happens for some movies (ie. http://www.omdbapi.com/?i=&t=four+rooms has it's Metascore set to N/A).
UPDATE #2 :
Another related inquiry. I'm using EF6 with MySQL and the idea's to populate the database with movies created through JSON parsing.
This is my Movie class :
[JsonObject(MemberSerialization.OptIn)]
[Table("movies")]
public class MovieJSON
{
[Key]
public int Id { get; set; }
[JsonProperty(PropertyName = "Title")]
[Column("title")]
public String Title { get; set; }
[JsonProperty(PropertyName = "Year")]
[Column("year")]
public int Year { get; set; }
[JsonProperty(PropertyName = "Genre")]
[Column("genre")]
public String Genre { get; set; }
[JsonProperty(PropertyName = "Director")]
[Column("director")]
public String Director { get; set; }
[JsonProperty(PropertyName = "Actors")]
[Column("actors")]
public String Actors { get; set; }
[JsonProperty(PropertyName = "Plot")]
[Column("plot")]
public String Plot { get; set; }
[JsonProperty(PropertyName = "Poster")]
[Column("poster")]
public String Poster { get; set; }
[JsonProperty(PropertyName = "Metascore")]
public String Metascore { get; set; }
[Column("metascore")]
public int MetascoreInt
{
get
{
int result;
if (int.TryParse(Metascore, NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result))
return result;
return 0;
}
}
[JsonProperty(PropertyName = "imdbRating")]
public String ImdbRating { get; set; }
[Column("imdb_rating")]
public Decimal ImdbRatingDecimal
{
get
{
Decimal result;
if (Decimal.TryParse(ImdbRating, out result))
return result;
return 0;
}
}
[JsonProperty(PropertyName = "imdbVotes")]
public String ImdbVotes { get; set; }
[Column("imdb_votes")]
public long ImdbVotesLong
{
get
{
long result;
String stringToParse = ImdbVotes.Remove(ImdbVotes.IndexOf(','), 1);
if (long.TryParse(stringToParse, out result))
return result;
return 0;
}
}
[JsonProperty(PropertyName = "imdbID")]
[Column("imdb_id")]
public String ImdbID { get; set; }
[JsonProperty(PropertyName = "type")]
[Column("type")]
public String Type { get; set; }
public override string ToString()
{
String[] propertiesToIgnore = {"MetascoreInt", "ImdbRatingDecimal", "ImdbVotesLong"};
var sb = new StringBuilder();
PropertyInfo[] properties = GetType().GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
if (propertiesToIgnore.Contains(propertyInfo.Name))
continue;
sb.AppendLine(String.Format("{0} : {1} ",
propertyInfo.Name, propertyInfo.GetValue(this, null)));
}
return sb.ToString();
}
}
This is my EF6 configuration-context class (I'm ignoring the String fields and instead, using the Helper ones since the database is configured to accept int for Metascore and so on) :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MovieJSON>().Ignore(e => e.Metascore).Ignore(e => e.ImdbRating).Ignore(e => e.ImdbVotes);
base.OnModelCreating(modelBuilder);
}
Additional image info :
Object values before insertion into the database (all values are properly set)
Valid XHTML http://imagizer.imageshack.us/v2/800x600q90/689/8x5m.png
Values in the database :
Valid XHTML http://imagizer.imageshack.us/v2/800x600q90/844/nvc5.png
The helper fields (MetascoreInt, ImdbRatingDecimal, ImdbVotesLong) are returning zero, I can't figure out why.
Any help would be mucho appreciated! :)
All the best
You could have two properties: one would be the string property as it comes from IMDB, and the other would be the int property that converts the string one. To convert, you can use the nifty NumberStyles.AllowThousands flag. So you would have
[JsonProperty(PropertyName = "imdbVotes")]
public string ImdbVotes { get; set; }
public int ImdbVotesInt
{
get
{
int result;
if (int.TryParse(ImdbVotes,
NumberStyles.AllowThousands,
CultureInfo.InvariantCulture,
out result))
return result; // parse is successful, use 'result'
else
return 0; // parse is unsuccessful, return whatever default value works for you
}
}

Getting error when loading data from db to class object

i have a class customer. in which i am trying to load data from the access db database.
Customer class structure is below:
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public string CustAddress { get; set; }
public string PnoneNo { get; set; }
public string MobileNo { get; set; }
public string CstNo { get; set; }
public string DlNo { get; set; }
public decimal BalAmt { get; set; }
}
and my table structure in db is as below:
now when i am trying to load data in customer class it is throwing an error:
"Specified cast is not valid."
for loading data in to class i am using below code:
public static List<Customer> LoadListItems(string strTable, string strOrderBy)
{
List<Customer> lstCustomer=null;
try
{
DataUtility objDataUtility = new DataUtility();
DataTable objCustomerList = objDataUtility.LoadCustomerInfo(strTable, strOrderBy);
lstCustomer= objCustomerList.AsEnumerable().Select(row =>
new Customer
{
CustomerId = row.Field<int>("CID"), //throwing error for this line
CustomerName = row.Field<string>("salPNm"),
CustAddress = row.Field<string>("cadd"),
MobileNo = row.Field<string>("cmbl"),
PnoneNo = row.Field<string>("cph"),
DlNo = row.Field<string>("cDlN"),
CstNo = row.Field<string>("cTin"),
BalAmt = row.Field<decimal>("cobal")
}).ToList();
}
catch (Exception ex)
{
throw ex;
}
return lstCustomer;
}
In above method CustomerId = row.Field<int>("CID"), is throwing an error coz when i commented this line it is working fine.
Please help me how can i get the int values from iennumrable list.
Thanks in Advance.
Eshwer
Replace it with -
CustomerId = Convert.ToInt64(row.Field<int>("CID"));
Also, check the value by applying Quick Watch over this line - row.Field<int>("CID"). See if it's not null and what's the value its returning.
Try this
public class Customer
{
public Int64 CustomerId { get; set; }
public string CustomerName { get; set; }
public string CustAddress { get; set; }
public string PnoneNo { get; set; }
public string MobileNo { get; set; }
public string CstNo { get; set; }
public string DlNo { get; set; }
public decimal BalAmt { get; set; }
}
and
CustomerId = row.Field<Int64>("CID")
I think that your identity is a long integer.

Categories

Resources