I am trying to build a grouped list for a windows phone app. When I use this query I get the grouped list, but it is not sorted:
return await _dbConnection.QueryAsync<Employee>(
"SELECT * FROM Employee WHERE Active = 1");
When I try to add an order by clause, I get zero results:
return await _dbConnection.QueryAsync<Employee>(
"SELECT * FROM Employee WHERE Active = 1 ORDER BY FirstName");
I know "FirstName" is the correct column name.
If you get an enumerable list from your QueryAsync method, you can just sort the list afterwards. This allows some flexiblity as well, so you can sort by other fields if you would need to in the future.
list.Sort(emp => emp.FirstName); //list would be the list you obtain from the query above.
Related
Hope you can help me.
In a trigger of firebase database function I'm trying to update the
object of a child without knowing the id.
So, I want to update the categoria elements by only knowing the of it, but without knowing the product one.
Please help...
You may first retrieve the categoria data. Assuming you know the first key (LNBxRLsPR0OY8-_Cnm) and you have one categoria item only (if more than one categoria will explain with another code snap)
firebase.database().ref('product/' + key + '/categoria').once('value', snapshot=>{
if (snapshot.exists()) var categoriaKey = Object.keys(snapshot.val()[0])
firebase.database().ref('product/' + key + '/' + categoriaKey).set(newCategoriaObject)
})
EDIT:
productList={}
firebase.database().ref('product').once('value', snap=>{
snap.forEach(p=>{
productList[p.key]=p.val().name;
})
})
with above product list object array. Scenario: You will need to show the list of products names to the user. Upon the user selected a product, then you may retrieve the key with below function.
function findKey(productList, selectedProductName) {
for (let key in productList)
if (productList[key] === selectedProductName) return key;
}
key = findKey(productList, selectedProductName);
So, with the above simple codes, you will get product key, selected by the user. If you don't have another scenario:)
Is there a way that I query only the first item appearing in the table in Dynamo DB? Like for instance if I have 20k records. I don't want to get all the 20k first, and then get the first. I want it to query only the first one found in the table without passing a primary key or a sort key.
Scan the table or index setting the Limit parameter to 1. If there is no filter expression this will return the first item.
From the DynamoDB documentation:
For example, suppose that you Scan a table with a Limit value of 6 and without a filter expression. The Scan result contains the first six items from the table.
Now suppose that you add a filter expression to the Scan. In this case, DynamoDB applies the filter expression to the six items that were returned, discarding those that do not match. The final Scan result contains six items or fewer, depending on the number of items that were filtered.
Query the table and get only the first result and only 1 object.
const params = {
TableName: "Logins",
Limit : 1
},
docClient = new AWS.DynamoDB.DocumentClient(),
returnObj = {};
docClient.scan(params, function(err, data){
if(err) {
console.log(err)
} else {
console.log(data)
}
I am fairly new in this realm and any help is appreciated
I have a table in Dynamodb database named Tenant as below:
"TenantId" is the hash primary key and I have no other keys. And I have a field named "IsDeleted" which is boolean
Table Structure
I am trying to run a query to get the record with specified "TenantId" while it is not deleted ("IsDeleted == 0")
I can get a correct result by running the following code: (returns 0 item)
var filter = new QueryFilter("TenantId", QueryOperator.Equal, "2235ed82-41ec-42b2-bd1c-d94fba2cf9cc");
filter.AddCondition("IsDeleted", QueryOperator.Equal, 0);
var dbTenant = await
_genericRepository.FromQueryAsync(new QueryOperationConfig
{
Filter = filter
}).GetRemainingAsync();
But no luck when I try to get it with following code snippet (It returns the item which is also deleted) (returns 1 item)
var queryFilter = new List<ScanCondition>();
var scanCondition = new ScanCondition("IsDeleted", ScanOperator.Equal, new object[]{0});
queryFilter.Add(scanCondition);
var dbTenant2 = await
_genericRepository.LoadAsync("2235ed82-41ec-42b2-bd1c-d94fba2cf9cc", new DynamoDBOperationConfig
{
QueryFilter = queryFilter,
ConditionalOperator = ConditionalOperatorValues.And
});
Any Idea why ScanCondition has no effect?
Later I also tried this: (throw exception)
var dbTenant2 = await
_genericRepository.QueryAsync("2235ed82-41ec-42b2-bd1c-d94fba2cf9cc", new DynamoDBOperationConfig()
{
QueryFilter = new List<ScanCondition>()
{
new ScanCondition("IsDeleted", ScanOperator.Equal, 0)
}
}).GetRemainingAsync();
It throws with: "Message": "Must have one range key or a GSI index defined for the table Tenants"
Why does it complain about Range key or Index? I'm calling
public AsyncSearch<T> QueryAsync<T>(object hashKeyValue, DynamoDBOperationConfig operationConfig = null);
You simply cant query a table only giving a single primary key (only hash key). Because there is one and only one item for that primary key. The result of the Query would be that still that single item, which is actually Load operation not Query. You can only query if you have composite primary key in this case (Hash (TenantID) and Range Key) or GSI (which doesn't impose key uniqueness therefore accepts duplicate keys on index).
The second code attempts to filter the Load. DynamoDBOperationConfig's QueryFilter has a description ...
// Summary:
// Query filter for the Query operation operation. Evaluates the query results and
// returns only the matching values. If you specify more than one condition, then
// by default all of the conditions must evaluate to true. To match only some conditions,
// set ConditionalOperator to Or. Note: Conditions must be against non-key properties.
So works only with Query operations
Edit: So after reading your comments on this...
I dont think there conditional expressions are for read operations. AWS documents indicates they are for put or update operations. However, not being entirely sure on this since I never needed to do a conditional Load. There is no such thing like CheckIfExists functionality as well in general. You have to read the item and see if it exists. Conditional load will still consume read throughput so your only advantage would be only NOT retrieving it in other words saving the bandwith (which is very negligible for single item).
My suggestion is read it and filter it in your application layer. Dont query for it. However what you can also do is if you very need it you can use TenantId as hashkey and isDeleted for range key. If you do so, you always have to query when you wanna get a tenant. With the query you can set rangeKey(isDeleted) to 0 or 1. This isnt how I would do it. As I said, would just read it and filter it at my application.
Another suggestion thing could be setting a GSI on isDeleted field and writing null when it is 0. This way you can only see that attribute in your table when its only 1. GSI on such attribute is called sparse index. Later if you need to get all the tenants that are deleted (isDeleted=1) you can simply scan that entire index without conditions. When you are writing null when its 0 dynamoDB wont put it in the index at the first place.
Here is a sample of my Firebase data:
I need to be able to search userFavorites for a given user (here, afaapy...) and return the results ordered by the values (timestamps) to get all the user's favorites in order of the date added to the database.
I can search by key as follows, and retrieve all favorites for the given user:
databaseRef.child("userFavorites").queryOrderedByKey().queryEqual(toValue: user.uid).observe(...)
But these favorties are ordered by their keys. If I try to order by value as follows, I get "Cannot use multiple queryOrderedBy calls!":
databaseRef.child("userFavorites").queryOrderedByKey().queryEqual(toValue: user.uid).queryOrderedByValue().observe(...)
How can I retrieve the favorites for a given user sorted by their value?
Second question: is there an easier way to retrieve data in the order it was added to the database?
You can't order the same ref multiple times as documented here
When you use a order or a filter method, it returns a Query Interface. See it as a filtered reference containing only a subset of the original data. It means that
databaseRef.child("userFavorites").orderByKey().equalTo(user.uid)
will not return userFavorite/${user.uid} but userFavorite filtered to show only the user.uid entry. You can see it by doing
databaseRef.child("userFavorites").orderByKey().equalTo(user.uid).ref.key
That should return 'userFavorites'
In your case, I see two options:
Keep going with orderByKey().equalTo() and sort the results yourself
Or use directly child() to get the user, then sort via Firebase (and don't forget to use the Firebase's snapshot.forEach to be sure you get the data in the query order):
databaseRef.child(`userFavorites/${user.uid}`).orderByValue().once('value', (snapshot) => {
if (snapshot.exists()) {
snapshot.forEach((child) => {
console.log(`${child.key}: ${child.val()}`)
})
}
})
Hi im trying to assign a default group to any user that registers with my site. Since the admin Id of that group is the administrator, I query my database for a group with a admin id of my administrator and then assign that group to the user. However the following error is being thrown
"Unable to cast object of type 'System.Data.Objects.ObjectQuery`1[DatabaseModel1.Group]' to type 'DatabaseModel1.Group'. "
Heres the code
Dim defaultGroup = (From group As Group In context.Groups
Where group.AdminID = ((From users As User0 In context.User0
Where users.Name Like "Administrator"
Select users.UserID).First)
Select group)
currentUser.Groups.Add(defaultGroup)//the error is being thrown here
any help would be appreciated
Thanks
It sounds like you've got a query which can return multiple results, but you're trying to assign it to a single-value variable.
You probably just need to use something like:
currentUser.Groups.Add(defaultGroup.First)
The probable options are:
First() - allows multiple results and returns the first; will throw an exception if there are none
FirstOrDefault() - allows multiple results and returns the first; will return the default value for the element type (e.g. null) if there are no results
Last() - allows multiple results and returns the last; will throw an exception if there are none
LastOrDefault() - allows multiple results and returns the last; will return the default value for the element type (e.g. null) if there are no results
Single() - expects exactly one result; if there are no results or mulitple results, an exception is thrown
Now that you've shown the query, it sounds like you should probably use a join rather than a nested query. I'm not hot on the VB query syntax, but in C# you might want:
var defaultGroupQuery =
from group in context.Groups
join user in context.User0 on group.AdminID equals user.UserID
where user.Name == "Administrator"
select group;
List<int> adminIDs = context.User0.Where(u=> u.Name.Contains("Administrator"))
.Select(u=>u.UserId);
//you can use `FirstOrDefault()` above and it will return only int not `List<int>`
// but i'm showing you how to get all IDs then you can get the first one
int adminId = adminIDs.FirstOrDefault();
//and then get only one Group using this adminID
var defaultGroup = context.Groups.FirstOrDefault(g=>g.AdminID == adminId);
if(defaultGroup != null)
{
currentUser.Groups.Add(defaultGroup);
}
//you can use the `List<int> adminIDs` if you need to get all admin groups
var groups = context.Groups.Where(gg => adminIDs.Contains(gg.AdminID));
Hope it helps.