Can any one help me with the following question?
In the Gosu code below, how can I include the city information in Address table in the result from the query (without turning the tables around - starting from Address table)? Address table has a foreign key point to user table, but no foreign key the other way. Can row query do that?
Thanks a lot
uses gw.api.database.Query
// -- query the User entity --
var queryUser = Query.make(User)
// -- select only User instances who last updated addresses in the city of Chicago --
var tableAddress = queryUser.join(Address, "UpdateUser")
tableAddress.compare("City", Equals, "Chicago")
// -- fetch the User instances with a for loop and print them --
var result = queryUser.select()
for (user in result) {
print (user.DisplayName)
}
Since Address has the user FK why not to turn the tables?
uses gw.api.database.Query
// -- query the Address entity --
var queryAddress = Query.make(Address)
queryAddress.compare("City", Equals, "Chicago")
// -- select only User instances who last updated addresses in the city of Chicago --
var tableUser = queryAddress.join(Address#UpdateUser)
// -- fetch the Addresses instances with a for loop and print them --
var result = tableUser.select()
for (address in result) {
print(address.City?.DisplayName)
print(address.UpdateUser?.DisplayName)
}
Related
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.
So the issue that I am having is getting the correct db items to work in the search in the web page, for some reason it does not search all of the values from Vehicle_Make that exist in Vehicle_Details - Make_ID is the primary key of Vehicle_Make and it is a FK in Vehicle_Details.
What happens is, it shows all the items on the page in a list, but the search does not work when I search for any of those items.
public class MapController : Controller
{
private GoogleMapEntities db = new GoogleMapEntities();
// GET: Map
public ActionResult Index()
{
GoogleMapEntities GE = new GoogleMapEntities();
List<Vehicle_Details> vehList = db.Vehicle_Details.ToList();
GoogleMapViewModel GMviewmodel = new GoogleMapViewModel();
List<GoogleMapViewModel> GMviewmodelList = vehList.Select(x=> new GoogleMapViewModel {
Make_Name = x.Vehicle_Make.Make_Name,
Make_ID = x.Vehicle_Make.Make_ID,
User_ID = x.User.User_ID,
MapLat = x.User.MapLat,
MapLong = x.User.MapLong
// Dealer_name = x.User.Dealer_name
}).ToList();
return View(GMviewmodelList);
}
[HttpPost]
public ActionResult Search(string Location)
{
GoogleMapEntities GE = new GoogleMapEntities();
////SELECT Make_Name DATA FROM DB1
var result = GE.Vehicle_Make.Where(x => x.Make_Name.StartsWith(Location)).ToList();
var GetVeh = (from vd in db.Vehicle_Details
join vm in db.Vehicle_Make
on vd.Make_ID equals vm.Make_ID
join u in db.User
on vd.User_ID equals u.User_ID
select vm).ToList();
//SELECT ALL ELEMENTS FROM Veh Make TABLE THAT EXISTS ON Veh Details TABLE BASED ON EXISTING ID's
var resultFinal = (from e in result
where !(from m in GetVeh
select m.Make_ID).Contains(e.Make_ID)
select e
).ToList();
return Json(resultFinal, JsonRequestBehavior.AllowGet);
}
}
Another weird thing that happens is, if I add the "!" in the following code, it does return the vehicle makes that do not exist in the vehicle details table but without the "!", it does not search for the values that do exist in both tables.
var resultFinal = (from e in result
where !(from m in GetVeh
select m.Make_ID).Contains(e.Make_ID)
select e
).ToList();
Sample Data:
BMW exists in Vehicle_Make(Make_ID PK) and Vehicle_Details(Make_ID FK).
Vespa exists in Vehicle_Make but not in Vehicle_Details
If I search for BMW it does not work but if I search for Vespa or any vehicle that does not exist in the Vehicle_Details table, it will find those, but not the vehicles that exist in both tables.
Once I get the correct items that need to be searched for like BMW, it must match the Dealerships(Users table) and take the MapLat & MapLong from the "Users" table and then pin point them onto the map.
Vehicle_Details has (User_ID FK) which is the PK of the Users Table.
Basically, Vehicle_Details has Users and Vehicle_Make linked to it, while Users and Vehicle_Make do not have a link in them so therefore vehicle details is the link. Is this possible to make work for what I require?
How to query range key programmatically in DynamoDB, I am using .Net AWSSDK ,I am able to query on Hash key with below code :
GetItemRequest request = new GetItemRequest
{
TableName = tableName
};
request.Key = new Dictionary<string,AttributeValue>();
request.Key.Add("ID",new AttributeValue { S = PKValue });
GetItemResponse response = client.GetItem(request);
Please suggest,
Thanks in advance.
There are two kinds of primary key in DynamoDB: Hash-only or Hash-Range.
In the above code I guess your table is Hash-only and you use the hash key to retrieve an element with hashkey equals to PKValue.
If your table is in H-R schema and you want to retrieve a specific element with a hashKey and rangeKey, you can reuse the above code and in addition, add the {"RangeKey", new AttributeValue } into your your request.KEY
On the other hand, query means a different thing in DynamoDB. Query will return you a list of rows sorted in some order.
I got the following issue. I am trying to use the With or WithMany instruction
to retrieve a linked list of roles of an business relation via an
outer join. The referential integrity is in place on the database but
the primary key on the roles table is a composite key. That's the
reason i use an OuterJoin clause because I get an exception
otherwise .
When the query gets executed the results are exactly as I expected and
nicely filled with data. Nevertheless there are certain cases where
there are not yet roles available in the database. So I would expect
that in those cases the returned SimpleList (Roles below) would be
null, cause there is not data available. Instead Simple.Data returns a
SimpleLIst and if i expand the Dynamic View in debug then it says
'Empty: No further information on this object could be discovered".
Even if i traverse further down and i retrieve the first object in the
SimpleList, it even returns a SimpleRecord with the same information
as above in debug. Only after I request a property of the SimpleRecord
I get some information that the record was empty because then it
returns null.
To come to the bottom line... is there anybody who can tell me how to
check if a SimpleList or SimpleRecord is empty or null without
traversing down the hierarchy?
I am using Simple.Data 0.16.1.0 (due to policy i can't use the
beta yet)
Thanks in advance for reading the whole story...
Below is the code sample:
dynamic businessRelationRoles;
var query = db.Zakenrelaties.As("BusinessRelations")
.All()
.OuterJoin(db.Zakenrelaties_Rollen.As("Roles"), out businessRelationRoles)
.On(zr_ID: db.Zakenrelaties.zr_ID)
.With(businessRelationRoles);
foreach (var relation in query)
{
//Get the SimpleList as IEnumerable
IEnumerable<dynamic> roles = relation.Roles;
//Get the first available SimpleRecord
var role = roles.First();
//Check if any record was returned..This passes always?? Even if the SimpleList was empty
if (role != null)
{
//Get the id of the role. returns null if SimpleRecord was empty
var roleId = role.zrro_id;
}
}
Is there anybody who can help me out?
Belatedly, and for information purposes only, this was a bug and got fixed in the 0.17 (aka 1.0-RC0) release.
I'm struggling to get a collection of records using L2E. Here's the model view:
http://pascalc.nougen.com/stuffs/aspnet_linq_model2.png
I have a user identifier, which is associated to 1 or many UserGroup which themselves are linked to TestCase. I would like to get all TestCases of all groups the user id X is associated to.
I also notice that I don't get all Project for users that are associated to 2 (or more).
Here's how I do so far:
QASModel.QASEntities qasEntities = new QASModel.QASEntities();
QASModel.User authenticatedUserEntity = (from u in qasEntities.Users
where u.ID.Equals(authenticatedUserId)
select u).FirstOrDefault();
// Get the authenticated user usergroups
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
// Get all testcases of all user group the authenticated user is associated to
var allTestcases = usergroup.TestCases;
// Get the authenticated user projects based on it's usergroup(s)
var authenticatedUserProjects = usergroup.Projects;
authenticatedUserProjects give back only 1 project, where the user is linked to 2 projects.
And allTestcases gives back no result, although there are about 8 entries in TestCases associated to a project associated to one of the same UserGroup the user belongs to.
Thanks
I think your problem is in this line:
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
Shouldn't your code get all UserGroups of that User? The above line will return only 1 UserGroup, this is, if the user belongs to more than 1 UserGroup the 2nd one won't be returned.
To correct this:
var userTestCases = new List<TestCase>();
var userProjects = new List<Project>();
foreach(UserGroup ug in authenticatedUserEntity.UserGroups)
{
userTestCases = userTestCases.Concat(ug.TestCases);
// Get the authenticated user projects based on it's usergroup(s)
userProjects = userProjects.Concat(ug.Projects);
...
}
var usergroup = authenticatedUserEntity.UserGroups.FirstOrDefault();
probably is wrong, since you want all usergroups the user is associated with.
In any case you can easily revert the query to work like this
var testcases = from tc in new QASModel.QASEntities().TestCases
where tc.UserGroup.UserId == USERID
select tc
This way you won't have to execute multiple queries to get all test cases, each FirstOrDefault or ToList or ForEach will actually execute the query.