Self Referencing Table LINQ - asp.net

Hello I have a table that has an "id" field and a "parentid" field. Both fields are required so you can't insert null into a parentid column to mark it as a "root" to the hierarchy. I'm having an issue with linq where when I create a new "root" I have to put in a dummy parentid until I know the id of the new root, then I have to updated the parentid field with the correct id and save it again. This seems silly, but I haven't found a better way to accomplish this yet?
TableWithHeirachy xobj = new TableWithHeirachy();
xobj.property1 = "test";
db.TableWithHeirachy.InsertOnSubmit(xobj);
db.SubmitChanges();
xobj.parentid = xobj.id;
db.SubmitChanges();
This seems really bad. Please tell me there is a better way!

A SQL Statement won't know the future ID of the row it's about to insert, until the insert has completed.
So, either continue as you are now - or instead use special values to indicate root records (null, -1, etc).

Related

DynamoDb - .NET Object Persistence Model - LoadAsync does not apply ScanCondition

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.

How to implement "And"-Condition in ydn db?

I need help in ydn db.
My issue is as follows: How can I fetch records by 2 conditions?
In sql it would be:
"SELECT * FROM store WHERE name='Test' AND cool=1;"
Currently my attempt looks like this:
var keyRange = ydn.db.KeyRange.bound(['Test', true]);
var db = DB.getDatabase();
database
.get('personStore', 'name, cool', keyRange)
.done(function(records) {
console.log(records);
});
Thanks in advance :-)
As discussed in this page, you can use compound index (as you did) or key joining. If you index ['name', 'cool'], you should be able to query by ydn.db.KeyRange.only(['Test', 1]). Note that boolean is not a valid key. Even if cool is boolean value, you have to index as integer value. But my suggestion is index only name and, just query name and filter out cool value on the result set.

Tridion Query for component that have no exact metadata field

I have a components that based on schema that have a non mandatory metadata field ExtendedType. I can query for a component that have this field with a certain value:
new CustomMetaValueCriteria(new CustomMetaKeyCriteria("ExtendedType"), "Highlight", Criteria.Equal)))
I need to query for a components that have no this field filled in. How can I query for a that.
In SQL I can write next:
select * from t where t.ExtendedType IS NULL
How can i do this using Trdion Query? In common i need to implement query like:
select * from t where t.ExtendedType = "Highlight" OR t.ExtendedType IS NULL
You might be able to achieve this with the NotInCriteria, as follows:
new NotInCriteria
(
new CustomMetaValueCriteria
(
new CustomMetaKeyCriteria("ExtendedType"), "%", Criteria.Like
)
)
I haven't tested this, it's just a thought. Even if it works, be sure to check if it performs as well!
PS: next time, please use the tridion.stackexchange.com forum for Tridion-related questions!

Linq query returning same row 12 times

Hi i have written one linq query to fetch records from entity model. I am getting perfect number of records but all are same.
here is my query
Entities.TEST.Where(a => a.ID.ToUpper().Equals(ID.ToUpper())).OrderBy(s => s.NAME).ToList();
Am I missing something?
You need to make sure your Entity Key in your Entity Data Model is unique.
So in your example, ID should be the entity key for your Test entity
Your query should work, i have a similar sample that works for northwind DB:
var ctx = new NorthwindEntities();
var emp = ctx.Employees.Where(e => e.TitleOfCourtesy.Equals("ms.", StringComparison.OrdinalIgnoreCase)).OrderBy(n => n.FirstName).ToList();
Please check your query in LinqPad. You will see the results and the generated SQL.
Replace Equals with == and you can go

How to check if SimpleList or SimpleRecord is empty

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.

Resources