Joins and anonymous types in SQLite - sqlite

I'm trying to do a few LINQ statements in SQLite but I'm getting a few problems.
First I'm trying to do a join. Here is my code:
var query = from client in db.Table<Client>()
join address in db.Table<AddressDetail>()
on client.AddressID equals address.AddressID
select new
{
ClientID = client.ClientID,
AddressID = address.AddressID,
Name = address.Name,
LastSaveDate = client.LastSaveDate
};
This fails and the error message I receive is : Joins are not supported.
Brilliant!!
So to get round this I split my code into 2 queries, so here is the updated code:
var query = db.Table<Client>();
foreach (var client in query)
{
var subQuery = from address in db.Table<AddressDetail>()
where address.AddressID == client.AddressID
select new
{
ClientID = client.ClientID,
AddressID = address.AddressID,
Name = address.Name,
LastSaveDate = client.LastSaveDate
};
foreach (var fullClient in subQuery)
{
//Do something here
}
}
This all seems to work until I try to loop round the results of the subQuery.
I receive the following error: No parameterless constructor defined for this object.
So do this mean that I can't use joins and anonymous types in SQLite?
Any ideas how I can get round this.
I'm using the SQLite, .Net 4.5 and am create a Windows 8 store app.

Had you try this?
just add ToList() to table you want to join.
var query = from client in db.Table<Client>()
join address in db.Table<AddressDetail>().ToList()
on client.AddressID equals address.AddressID
select new
{
ClientID = client.ClientID,
AddressID = address.AddressID,
Name = address.Name,
LastSaveDate = client.LastSaveDate
};

Related

Get the last inserted item using Document Model or Object Persistence Model using .Net core with DynamoDB

I am able to get the last inserted item using low level API as showed in code below using .net core
But is it possible to get the last inserted item using high level API such as Document Model or Object Persistence Model?
Prefer Object Persistence Model if possible. I am not able to find a way to do it, also, I would like DynamoDB to query and return the last item only. I understand that I can get a list of items inserted and get the last item myself in memory, but it is not preferable since it require a lot more read and data transfer.
Thanks
public async Task<DailyStockRecordDao> GetTheLastInsertedItem(string tickerSymbol)
{
QueryRequest request = getTheLastItemRequest(tickerSymbol);
var response = await _dynamoDBClient.QueryAsync(request);
return null;
}
private static QueryRequest getTheLastItemRequest(string tickerSymbol)
{
string partitionName = ":v_PartitionKeyName";
var request = new QueryRequest
{
TableName = Constants.TableName,
KeyConditionExpression = $"{Constants.PartitionKeyName} = {partitionName}",
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{ $"{partitionName}", new AttributeValue {
S = tickerSymbol
} }
},
// Optional parameter.
ConsistentRead = false,
Limit = 1,
ExclusiveStartKey = null,
ScanIndexForward = false
};
return request;
}
You can have the below data-structure to achieve this.
pk value
----------------------------------------------
key1 value1
key2 value2
key3 value3
latest {key: key1, value:value1}
While doing write, do 2 writes instead of 1. and while reading just do a get using pk=latest.
Can you add one more column called created_counter, and insert the value starting with numeric 1, then 2, then 3 and so on?
Make the created_counter as sort key.
To reverse the order, set the ScanIndexForward parameter to false.
Use limit 1, to get the last inserted data.

What is the Partiton Key value when it's null?

I've got records that were the result of bad data where the Partition Key is null and I need to clean them up, but I've been unsuccessful so far.
Here's what I've tried:
var scriptResult = await _dbClient.ExecuteStoredProcedureAsync<dynamic>(
GetStoredProcLink("BulkDelete"),
new RequestOptions() { PartitionKey = new PartitionKey(""), EnableScriptLogging = true },
"select * from c where c.documentDbType = "SomeValue"");
I've also tried used Undefined.Value as the parameter to new PartitionKey().
I ripped the stored proc from here and haven't changed anything yet.
Note: This is a partitioned collection if it was not obvious (by /companyId)
I just hit this issue when migrating to new database level throughput provision. This is syntax that got me up and running again when my models did not contain the specified partition Key property:
new RequestOptions() {
PartitionKey = new PartitionKey(Undefined.Value)
}
Ref:
https://www.lytzen.name/2016/12/06/find-docs-with-no-partitionkey-in-azure.html
Null, Undefined, and empty string are all different values in Cosmos DB. You need something like: new RequestOptions { PartitionKey = new PartitionKey(null) }

How to get the count of the rows matching to the condition specified in SQLITE Ionic app

I am developing a mobile application with Ionic and SQLITE database. I want a scenario where same record should not be inserted twice for Inventory operation. I am checking the database as follows:
var query = "SELECT COUNT(*) FROM productScan WHERE uniqueId = (?) AND sync = \'N\'";
$cordovaSQLite.execute(db, query, [uniqueId]).then(function (res) {
alert(JSON.stringify(res));
}, function (err) {
alert(JSON.stringify(err));
});
what happen here is when i install the app for the first time and run it then after scan operation when this code run for duplication check, it gives me following output even though there is no record in database
{"rows":{"length":1},""rowsAffected":0}
I am new to Structured Query Language(SQL). I am not able to parse the result here. The result is coming wrong. Is the query needs to be reformatted or any different way to achieve the goal?
Thanks for your time.
BEST way to do this is by giving ALIAS to the COUNT(*) .
something like this
db.executeSql("select count(*) AS TOTAL from mydebit where aid = ?", [
parseInt(this.mydata)
]);
and then
console.log(data.rows.item(0).TOTAL)
so we can easily give the name to the return result and use the to get he row value
cheersss.....!!!!!!!!!
I do it in this way
JSON.stringify(data.rows.item(0)['COUNT(*)'])
Somehow i managed to achieve it in a different way
var query = "SELECT * FROM productScan WHERE uniqueId = (?) AND sync = \'N\'";
$cordovaSQLite.execute(db, query, [uniqueId]).then(function (res) {
if (res.rows.length == 0) {
//processed the operation
}else{
alert('You have already scanned this asset!.');
}
var query = "SELECT COUNT(*) FROM productScan WHERE uniqueId = (?) AND sync = \'N\'";
$cordovaSQLite.execute(db, query, [uniqueId]).then(function (res) {
just parse the result,(json.parse(res)) and find by rowsAffected like
if(rowsAffected != 0)
{
//just do the operation
}
else {
//terminate
}

AngularFire return last sorted record by custom key value

I have a collection of data in Firebase that uses my own custom keys to match what we are expecting from our API when it is completed. However, I need to get the highest value from a key that we created.
Data:
-Results
+20150514-1
+20150514-2
-20150521-1
Field1: data
Field2: data
...
+20150521-2
+20150528-1
+20150528-2
+20150528-3
+20150528-4
+20150604-1
+20150604-2
+20150604-3
In this case the key fields under my Results are dates with instances, then full records under each instance (Field1, Field2, ...). I am getting the data using
var FireBaseData = new Firebase(FIREBASE.URL);
var Results = FireBaseData.child('Results');
var LastResult = Results.orderByPriority().limitToLast(1);
var LastDate = LastResult.$id;
return LastDate.substr(0, 8);
However, I am now trying to get access to the $id, or even a data field in that last record, but I cannot get data.
I have also tried:
factory('Result' ...
var FireBaseData = new Firebase(FIREBASE.URL);
var Results = FireBaseData.child('Results');
var LastResult = Results.orderByPriority().limitToLast(1);
return $firebaseObject(LastDate);
and then try to access the Field on the returned item, without success.
var myDate = Result.Field2;

Entity framework select from two tables with different table relationship primary/foreign key scenarios

I have two sample tables:
SCENARIO 1
TABLE 1 - INGREDIENT
ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
TABLE 2 - INGREDIENT ADDITIONAL INFORMATION
ingredientAdditionalInformationId(PK, int, not null)
ingredientId(FK, int, not null)
isApproved(bit, not null)
unitsConverted(bit, not null)
SELECT SENTENCE IN CODE BEHIND:
public IQueriable GetIngredientData(int ingredientId)
{
using (var context = new MyEntities())
{
var result = context.Ingredient
.Where(i => i.ingredientId == ingredientId)
.Select(i => new
{
i.ingredientId,
i.userId
i.IngredientAdditionalInformation.FirstOrDefault(iai => iai.ingredientId = i.ingredientId).isApproved
i.IngredientAdditionalInformation.FirstOrDefault(iai => iai.ingredientId = i.ingredientId).unitsConverted
});
return result.ToList().AsQueriable();
}
}
or select with join (I know that you can join with method syntax but I can write join with query method faster)
public IQueriable GetIngredientData(int ingredientId)
{
using (var context = new MyEntities())
{
var result = from i in context.Ingredient
join iai in context.IngredientAdditionalInformation on i.ingredientId equals iai.ingredientId
where i.ingredientId == 1
select new
{
i.ingredientId,
i.userId
iai.isApproved
iai.unitsConverted
};
return result.ToList().AsQueriable();
}
}
Which one is better/faster with join or FirstOrDefault() or I should write database table different like in example 2 below:
SCENARIO 2
TABLE 1 - INGREDIENT
ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
TABLE 2 - INGREDIENT
ingredientId(PK, FK, int, not null) //WITHOUT PRIMARY (ingredientAdditionalInformationId) AUTO INCREMENT KEY)
isApproved(bit, not null)
unitsConverted(bit, not null)
Because I know that every ingredient have only one additional info...
SELECT SENTENCE IN CODE
using (var context = new MyEntities())
{
var result = context.Ingredient
.Where(i => i.ingredientId = 1)
.Select(i => new
{
i.ingredientId,
i.userId
i.IngredientAdditionalInformation.isApproved
i.IngredientAdditionalInformation.unitsConverted
});
}
I would like to know which table design is better (SCENARIO1 or SCENARIO2) for optimized select, if I really need auto increment key in ingredientAdditionalInformation if I know that there will be only one entry for every Ingredient and if this is the right way to use entity framework?
If you're maintaining a one-to-one relationship between the two tables, then your second design is better, because it will also ensure referential integrity in your database.
You can then make the property a single navigation property in your entity framework model, and simplify your EF query as follows. If you have lazy loading of navigational properties enabled in your model, you may be able to get away without using the include if you're
var result = from i in context.Ingredient.Include("IngredientAdditionalInformation") select i;
And then access the properties as follows:
i.IngredientAdditionalInformation.isApproved
However, do you really need an additional table? With only three properties on each I'd just combine them into one table and then you have all the properties available to you immediately.
Scenario 2 is better since you are saying there is a one-to-one relationship between the two tables.
Another option you should explore is using Table Per Type Inheritance. You will not need to specify eager loading using Include nor joins in this case.
Assuming your table1 = IngredientBase and table2 = Ingredients and in your context you have set up
public IQueryable<Ingredient> Ingredients {
get { return IngredientBases.OfType<Ingredient>(); } }
then you'll just need
using (var context = new MyEntities())
{
var result = context.Ingredients.Where(i => i.ingredientId = 1);
}
SQL wise, the 2nd select of scenario1 and scenario2 will produce nearly equivalent plans. But performance wise, scenario2 will be better, not to mention being the right design for a 1-1 relationship tables.

Resources