How to select dynamic column in Xamarin forms SQL Lite - c#

I using Xamarin forms. I would like to select my dynamic column using SQL Lite Query but I got an error.
Here is My model :
public class MyWords
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
[JsonProperty(PropertyName = "id")]
public Guid MyId { get; set; } = Guid.NewGuid();
[JsonProperty(PropertyName = "languagevalue1")]
public string LanguageValue1 { get; set; }
[JsonProperty(PropertyName = "languagevalue2")]
public string LanguageValue2 { get; set; }
[JsonProperty(PropertyName = "languagevaluecombine")]
public string LanguageValueCombine { get { return LanguageValue1 + " " + Separator + " " + LanguageValue2; } }
}
I would like to get the value of the column "languagevaluecombine" but I have an error.
Here is how I query my column "languagevaluecombine" table :
var ListCombine = conn.QueryAsync<MyWords>("select DISTINCT languagevaluecombine from MyWords ");
Here is the error that got :
SQLite.SQLiteException has been thrown
no such column: languagevaluecombine
But When I try with the column "languagevalue2" I works as it is not a dynamic columns
Thanks for your help

Related

Database reading to list<T> for display returning null values for some columns that already have values (asp.net mvc)

I have created a database for saving movie details using an ASP.NET MVC web application. I can add data to the database. Inside the database it is showing values in all columns. But when I retrieve data from the table using this statement
return cnn.Query<T>(sql).ToList();
the retrieved list contains null values for 6 columns (C_Category, FilmName, Filmid, D_Cost, P_Cost) [Poster is also null because I haven't added the code for converting the file upload to bytes. That is to be added] But these 6 columns have their respective values in the database.
Is there any way to correct my code to read from database properly? Can you please suggest anything?
I tried adding a breakpoint at the above return statement and viewed the list, which showed up the error values in it before it is passed to further stages. The project builds without any errors and runs but displays these nulls.
The following is the SQL Server data access class file's code
public static List<T> LoadData<T>(string sql)
{
using (IDbConnection cnn = new SqlConnection(GetConnectionSring()))
{
return cnn.Query<T>(sql).ToList();
}
}
This is my business logic class:
public static List<FilmAddModel> LoadFilm()
{
string sql = #"select * from dbo.Film;";
return SqlDataAccess.LoadData<FilmAddModel>(sql);
}
And this is my model for dB display and write
public class FilmAddModel
{
public int Filmid { get; set; }
public string FilmName { get; set; }
public string Actor { get; set; }
public string Actress { get; set; }
public string Pub_Date { get; set; }
public string Director { get; set; }
public string Producer { get; set; }
public decimal P_Cost { get; set; }
public decimal D_Cost { get; set; }
public string Category { get; set; }
public string C_Category { get; set; }
public byte[] Poster { get; set; }
}
Here's my home controller code to use the above for displaying the database contents:
public ActionResult ViewFilm()
{
ViewBag.Message = "Movies List";
var data = LoadFilm();
List<FilmAddModel> movies = new List<FilmAddModel>();
foreach (var row in data)
{
movies.Add(new FilmAddModel
{
Filmid = row.Filmid,
FilmName = row.FilmName,
Actor = row.Actor,
Actress = row.Actress,
Pub_Date = row.Pub_Date,
Director = row.Director,
Producer = row.Producer,
P_Cost = row.P_Cost,
D_Cost = row.D_Cost,
Category = row.Category,
C_Category = row.C_Category,
Poster = row.Poster
});
}
return View(movies);
}
Following is my database structure
CREATE TABLE [dbo].[Film]
(
[Film_id] INT IDENTITY (1, 1) NOT NULL,
[film_name] VARCHAR(50) NULL,
[actor] VARCHAR(50) NULL,
[actress] VARCHAR(50) NULL,
[pub_date] VARCHAR(50) NULL,
[director] VARCHAR(50) NULL,
[producer] VARCHAR(50) NULL,
[prod_cost] DECIMAL(18) NULL,
[dist_cost] DECIMAL(18) NULL,
[category] VARCHAR(30) NULL,
[cert_category] VARCHAR(20) NULL,
[poster] VARBINARY(MAX) NULL,
PRIMARY KEY CLUSTERED ([Film_id] ASC)
);
The names of your SQL Server table columns and your C# model class don't match - you have e.g. film_name in the table, and FilmName in the C# model class - same goes for cert_category in SQL Server, and C_Category in C#.
If you have such differences in name, you need to decorate your C# model class with data annotations - something like:
public class FilmAddModel
{
[Column("film_id")]
public int Filmid { get; set; }
[Column("film_name")]
public string FilmName { get; set; }
public string Actor { get; set; }
public string Actress { get; set; }
public string Pub_Date { get; set; }
public string Director { get; set; }
public string Producer { get; set; }
[Column("prod_cost")]
public decimal P_Cost { get; set; }
[Column("dist_cost")]
public decimal D_Cost { get; set; }
public string Category { get; set; }
[Column("cert_category")]
public string C_Category { get; set; }
public byte[] Poster { get; set; }
}
With these data annotations, the mapping should be done properly between the values in your SQL Server table, and the C# model class.
As a side note: the LoadFilm method returns a List<FilmAddModel> - so why are you creating a second List<FilmAddModel> in your ViewFilm action method and iterate over the list return to add the same type of data into the result list?? You could just simply return the data returned from LoadFilm - it's already in the "right" shape ....
When you converting data to model inside foreach loop you didn’t use the correct name for those field to retrive from database.
Use
C_Category = row.cert_category
Filmid = row.Film_id
etc.
that means according to fieldname inside your data object.

Is this a good way to set more properties value after query?

This is what I do to set more properties value after query. Please see the method GetMoreData(), it will be executed for every detail loop and starts causing performance issue.
Is there a better way of doing this? I know the class constuctor that execute during object instantiate. But in this case, more properites must be set after database query.
Note: This is a cut-down version of source code focusing on important part only, please accept typo error, if any.
public class OrderHeader
{
// Real database column
public string OrderId { get; set; }
public string ColA { get; set; }
public string ColB { get; set; }
public string PostCode { get; set; }
public decimal TotalWeight { get; set; }
public decimal TotalShipmentFee { get; set; }
}
public class OrderDetail
{
// Real database column
public string OrderId { get; set; }
public string OrderLine { get; set; }
public decimal Weight { get; set; }
public decimal ShipmentFee { get; set; }
// mock-up column for displaly only, not exist in datababse
public string ColA { get; set; }
public string ColB { get; set; }
}
public static List<OrderDetail> GetByItemClass(string itemClass)
{
using (IDbConnection db = new MySqlConnection(connectionStringGoesHere)) {
string sqlCmd = #"SELECT * FROM orderdetail WHERE ItemClass = #ItemClass";
List<OrderDetail> orderDetails = db.Query<OrderDetail>(sqlCmd, new {
#ItemClass = itemClass
}).ToList();
// Get or build or calculate additional properties
for (int i = 0; i < orderDetails.Count; i++) {
orderDetails[i] = GetMoreData(orderDetails);
}
return orderDetails;
}
}
public static List<OrderDetail> GetByItemType(string itemType)
{
using (IDbConnection db = new MySqlConnection(connectionStringGoesHere)) {
string sqlCmd = #"SELECT * FROM orderdetail WHERE ItemType = #ItemType";
List<OrderDetail> orderDetails = db.Query<OrderDetail>(sqlCmd, new {
#ItemType = itemType
}).ToList();
// Get or build or calculate additional properties
for (int i = 0; i < orderDetails.Count; i++) {
orderDetails[i] = GetMoreData(orderDetails);
}
return orderDetails;
}
}
public static OrderDetail GetMoreData(OrderDetail orderDetail)
{
// Performance problem: Need to query order header for every
// single loop even multiple records having the same OrderId
OrderHeader orderHeader = OrderHeaderDal.GetById(orderDetail.OrderId);
// Directly map value
orderDetail.ColA = orderHeader.ColA;
orderDetail.ColB = orderHeader.ColB;
// Calculate value
if (orderHeader.PostCode == "0") {
orderDetail.ShipmentFee = orderDetail.Weight * 1.15;
// More complex to get value from another table
} else {
// Might also cause performance issue for many query loop
Rate rate = RateDal.GetByPostCode(orderHeader.PostCode);
orderDetail.ShipmentFee = orderDetail.Weight * rate.RatePerKg;
}
return orderDetail;
}

How to insert data from MS Access to SQL after checking whether the data exists or not in the database using Entity Framework

Hopefully, the question header is clear enough to tell that I'm trying to read an Access file and upload the data to the database but checking at first whether the data already exists or not in the database.
I receive a daily report from a third-party company in Access file. I'm trying to create a windows service that will check for the file every morning, and if the new file exist, then it'll read and upload the data to the database. I'm trying to use Entity Framework. I read the article on Navigation Property, but I'm still confused on that; I never used navigation property before. Here are my models:
[Table("ClaimsTable")]
public partial class ClaimsTable
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int ClaimsID { get; set; }
public string EOPAID { get; set; }
public string AuthID { get; set; }
public string PAStatus { get; set; }
public string UserName { get; set; }
[DataType(DataType.Date)]
public DateTime EffectiveDate { get; set; }
[DataType(DataType.Date)]
public DateTime EndDate { get; set; }
public string RecordType { get; set; }
public int RxID { get; set; }
public int MemberID { get; set; }
public int PrescriberID { get; set; }
public string EditNumber { get; set; }
public string OriginSource { get; set; }
public string OriginMethod { get; set; }
/*
[ForeignKey("RxID")]
public virtual RxTable Prescription { get; set; }
[ForeignKey("MemberID")]
public virtual MembersTable Member { get; set; }
[ForeignKey("PrescriberID")]
public virtual PrescribersTable Prescriber { get; set; }
*/
}
...
[Table("MembersTable")]
public partial class MembersTable
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int MemberID { get; set; }
[DataType(DataType.Date), Display(Name= "Date of Birth"), DisplayFormat(DataFormatString="{0:mm/dd/yyyy}", ApplyFormatInEditMode=true)]
public DateTime DateofBirth { get; set; }
public string CardholderID { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
//public virtual ICollection<AddressTable> Address { get; set; }
}
...
[Table("PrescribersTable")]
public partial class PrescribersTable
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int PrescriberID { get; set; }
public string NPI { get; set; }
public string PrescriberFirstName { get; set; }
public string PrescriberLastName { get; set; }
public string PhysicianType { get; set; }
//public ICollection<AddressTable> Address { get; set; }
}
....
using(OleDbConnection conn = new OleDbConnection(strDSN))
{
OleDbDataReader reader = null;
OleDbCommand command = new OleDbCommand("Select * from table", conn);
try
{
conn.Open();
}
catch(OleDbException o)
{
return o.Message;
}
reader = command.ExecuteReader();
List<ClaimsTable> Claim = new List<ClaimsTable>();
List<PrescribersTable> PrescriberInDB = new List<PrescribersTable>();
List<MembersTable> MembersInDB = new List<MembersTable>();
while(reader.Read())
{
PrescriberInDB = context.Prescribers.ToList();
MembersInDB = context.Members.ToList();
//CREATE LOCAL VARIABLE
string recordType = //check if the member and the prescriber exist in the database
int prescriberID = 0;
int prodID = 0;
int memberID = 0;
int drugID = 0;
int RxID = 0;
int claimID = 0;
//check if the member and the prescriber exist in the object before inserted into the database.
//the data will be uploaded to the database in bulk
//int newPrescriberID = Prescriber.Where(x => x.PrescriberFirstName == reader["Prescriber First Name"] && x.PrescriberLastName == reader["Prescriber Last Name"] && x.NPI == reader["Prescribing Physician"]).Select(x => x.PrescriberID).FirstOrDefault();
//int newMemberID = Member.Where(x => x.MemberFirstName == reader["Member First Name"] && x.MemberLastName == reader["Member Last Name"] && x.CardholderID == reader["CardhHolder"]).Select(x => x.MemberID).FirstOrDefault();
//insert the data if it doesn't exist
if(!PresciberExist(prescriberFirstName, prescriberLastName, npi, PrescriberInDB))
{
var prescriber = new PrescribersTable()
{
PrescriberFirstName = prescriberFirstName,
PrescriberLastName = prescriberLastName,
NPI = npi,
PhysicianType = physicianType
};
context.Prescribers.Add(prescriber);
context.SaveChanges();
prescriberID = GetPrescriberID(prescriberFirstName, prescriberLastName, physicianType, PrescriberInDB);
}
if(!MemberExist(memberFirstName, memberLastName, cardholderID, MembersInDB))
{
var member = new MembersTable()
{
MemberFirstName = memberFirstName,
MemberLastName = memberLastName,
CardholderID = cardholderID,
DateofBirth = dob
};
context.Members.Add(member);
context.SaveChanges();
memberID = GetMemberID(memberFirstName, memberLastName, cardholderID, MembersInDB);
}
}
}
return "Done uploading";
}
private bool MemberExist(string memberFirstName, string memberLastName, string cardholderID, List<MembersTable> MembersInDB)
{
return MembersInDB.Exists(x => x.MemberFirstName == memberFirstName && x.MemberLastName == memberLastName && x.CardholderID == cardholderID);
}
private bool PresciberExist(string prescriberFirstName, string prescriberLastName, string npi, List<PrescribersTable> PrescriberInDB)
{
return PrescriberInDB.Exists(x => x.PrescriberFirstName == prescriberFirstName && x.PrescriberLastName == prescriberLastName && x.NPI == npi);
}
The access database contains sensitive information, so I won't be able to add those data as an example. But here's a made up data for test. The data contains claims of patients.
Now, because there are many drugs and many claims for the same patient, and many patients for a prescriber.. I broke the database as it's shown above. Needs improvement? I welcome suggestion. The reason I did this is because I don't want my database to have repeated records which will make managing really troubling. This way, I'll have unique members in memberstable, unique prescribers in prescriberstable and so on and so forth.
The challenge I'm facing is that when I read the data from the access database, I'm assuming it reads row-wise. The code should first check the database whether the member exist or not. If it does, then get the member id which is an identity column. If it doesn't, then it should insert the member's info only, and then get the memberID. Similarly, I do the same thing with the prescriber's data. Check and insert if needed. This is the long way, and this is the only way I could figure out how to do it.
I know this is not a very good programming. I'm just an analyst who unfortunately has to do a lot of programming. And I'm learning as I go. With that said, there's a lot of ways to improve this code - I just don't know any. Can you point me to the right direction? Also, an example of how to check and insert the data if it doesn't exist in the database using navigation property. Currently, the data is read and uploaded just fine, but I saw in the database that it didn't quite do what I wanted it to do. It still added a couple of already existing members. I seriously needs some help.

Error inserting record with entity framework

I am sorry if it has already been answered but I can't find any solution. Here is my (little) problem. Also all my apologies if the terms I use are approximate, I am far from being a skilled C# developer
Note that I think my problem is similar to this one Entity Framework validation error for missing field, but it's not missing?
I have a table "Tweets" with a tweet_id field (bigint) which is my primary key.
I use the following class to load the table :
class TwitterDbContext : DbContext
{
public TwitterDbContext() : base("Twitter")
{
}
public DbSet<Stream> Streams { get; set; }
public DbSet<StreamParameter> StreamParameters { get; set; }
public DbSet<Tweet> Tweets { get; set; }
}
public class Tweet
{
public Tweet()
{
}
[Key]
public long tweet_id { get; set; }
public string tweet { get; set; }
public long creator { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public string language { get; set; }
public DateTime created_at { get; set; }
public DateTime registered_at { get; set; }
public long? in_reply_to { get; set; }
public bool retweeted { get; set; }
}
I have an other class to store within the code execution all the fields used by the Tweet table. For the need here, let's imagine I manually create it that way
private void Test_Button_Click(object sender, RoutedEventArgs e)
{
Twts twtReceived = new Twts();
twtReceived.tweet_id = 1;
twtReceived.tweet = "test";
twtReceived.creator = 1;
twtReceived.latitude = -1;
twtReceived.longitude = -1;
twtReceived.language = "a";
twtReceived.created_at = DateTime.Now;
twtReceived.registered_at = DateTime.Now;
twtReceived.in_reply_to = 1;
twtReceived.retweeted = true;
AddTweet(twtReceived);
}
Now here is the AddTweet method
static public void AddTweet(Twts twtReceived)
{
try
{
// update the tweet data in the database
using (var TwitterDb = new TwitterDbContext())
{
Tweet twt = new Tweet()
{
tweet_id = twtReceived.tweet_id,
tweet = twtReceived.tweet,
creator = twtReceived.creator,
longitude = twtReceived.longitude,
latitude = twtReceived.latitude,
language = twtReceived.language,
created_at = twtReceived.created_at,
registered_at = twtReceived.registered_at,
in_reply_to = twtReceived.in_reply_to,
retweeted = twtReceived.retweeted
};
TwitterDb.Tweets.Add(twt);
TwitterDb.SaveChanges();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}
}
I constantly have the same error message:
Cannot insert the value NULL into column 'tweet_id', table
'Twitter.dbo.Tweets'; column does not allow nulls. INSERT fails.
The thing is that when I spy on "TwitterDb.Tweets.Local" after TwitterDb.Tweets.Add(twt); I correctly have tweet_id set to 1.
Any idea where is the issue?
Try marking your tweet_id field with following (instead of just [Key]), if this is a primary key column where you want to provide values yourself
[Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
If it is an auto-increment, then remove explicit assignments to this field and mark it as 'Identity' instead:
[Required, Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

c# Deserialize Nested json

I am new to working with json - I am working with an existing json data structure and trying to output the data, however part of the existing data structure has me stumped.
The following is my json data:
{"supplier":
{
"supplierid":3590,
"code":"ENCLES",
"name":"Les Miserables",
"analyses":[],
"amenities":[],
"info":
"{\"Supplier\":
{
\"Name\":\"Les Miserables\",
\"LastUpdate\":\"2011-11-01T22:16:06Z\",
\"Address3\":\"London\",
\"Address2\":\"51 Shaftesbury Avenue\",
\"PostCode\":\"W1D 6BA\",
\"Address1\":\"Queen's Theatre\",
\"Address4\":\"\",
\"Address5\":\"\",
\"SupplierId\":3590,
\"SupplierCode\":\"ENCLES\"
}
}",
...
}
The bit that has me stumped is the info data - it is another nested json string.
My class is:
public class TheatreListing
{
public supplier supplier;
}
public class supplier
{
public int? supplierid { get; set; }
public string code { get; set; }
public string name { get; set; }
public listingInfo info { get; set; }
}
public class listingInfo
{
public Address Supplier { get; set; }
}
public class Address
{
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string Address4 { get; set; }
public string Address5 { get; set; }
public string PostCode { get; set; }
}
My code to try and access the data is:
TheatreListing tl = Json.Decode<TheatreListing>(json);
StringBuilder sbb = new StringBuilder();
sbb.Append("Name = " + tl.supplier.name.ToString());
sbb.Append("<br />Supplier ID = " + tl.supplier.supplierid.ToString());
sbb.Append("<br />Code = " + tl.supplier.code.ToString());
sbb.Append("<br />Address = " + tl.supplier.info.Supplier.Address2.ToString());
litOutput.Text += sbb.ToString();
The error message I am getting is:
Cannot convert object of type 'System.String' to type 'listingInfo'
Can anyone please guide me on the error of my ways here ?
Cheers
Nigel
I recommend looking at a couple of things:
1) Use json2csharp to generate your c# classes from your existing json
2) Use json.net to deserialize your json, works like a champ!
The problem is inside the line
TheatreListing tl = Json.Decode<TheatreListing>(json);
I think the conversion to TheatreListing is failed for your current json.
Why dont you try using JavascriptSerializer and see whether it works or not.
JavaScriptSerializer js = new JavaScriptSerializer();
TheatreListing tree = js.Deserialize <TheatreListing>(json);

Categories

Resources