SubSonic Multiple column primary key - subsonic

we have certain tables where we have multiple columns which together make the primary key.
When SubSonic generates all it's classes for our tables for the tables with multiple columns there are still methods, like FetchByID, that only use one value for the primary key.
Because of this the foreign key property will return the wrong items. For instance we have a product table that has a primary key of multiple columns. A class with a relation to the product table will have a product property with the get method like : Product.FetchByID(this.SalesOrganisationID). This should be Product.FetchByID(this.SalesOrganisationID, this.ProductID).
Does anyone have any advice for me about what i should do to make SubSonic work with these kind of primary keys?

You could expand your Product class to have a method that uses a Select to find the Product by it's composite id, for example:
public partial class Product{
public static Product FetchByCompositeId(int salesOrganisationId, int productId){
return DB.Select().From<Product>()
.Where(Product.Columns.SalesOrganisationId).IsEqualTo(salesOrganisationId)
.And(Product.Columns.ProductId).IsEqualTo(productId)
.ExecuteSingle<Product>();
}
}

You will have to get it using Query or SqlQuery (SubSonic.Select). You can add the method in the partial class of the Object you are adding this functionality, so as to encapsulate the details of performing the operation.

Related

JOOQ join two tables with same column names

I'm using running following JOOQ query:
dsl.select().from(table).join(joinTable).on(joinCondition).where(condition).fetchInto(entityClass);
Both table and joinTable have id as primary key name, but resulting fetch into entity class contains id of joinTable, and rest of columns of table. If I reorder tables, result is similar, I have ID from table and rest of columns from joinTable.
Metamodel is generated using jooq-codegen-maven plugin.
Interesting, I found out that using:
dsl.select(table.fields())...
solves problem. I would expect that this behavior is by default, but it is not.

Understanding Cassandra Data Model

I have recently started learning No-SQL and Cassandra through this article. The author explains the data model through this diagram:
The author also gives the below column family example:
Book {
key: 9352130677{ name: “Hadoop The Definitive Guide”, author:” Tom White”, publisher:”Oreilly”, priceInr;650, category: “hadoop”, edition:4},
key: 8177228137{ name”” Hadoop in Action”, author: “Chuck Lam”, publisher:”manning”, priceInr;590, category: “hadoop”},
key: 8177228137{ name:” Cassandra: The Definitive Guide”, author: “Eben Hewitt”, publisher:” Oreilly”, priceInr:600, category: “cassandra”},
}
But in that tutorial and every other tutorial I have gone through, then end up creating regular tables in cassandra. I am unable to connect the Cassandar model with what I am creating.
For example, I created a column family called Employee as below:
create columnfamily Employee(empid int primary key,empName text,age int);
Now I inserted some data and my column family looks as this:
For me this looks like a regular relational table and not like the data model the author has explained. How do I create a Employee column family where each row represents an employee with different attributes? Something like:
Employee{
101:{name:Emp1,age:20}
102:{name:Emp2,salary:1000}
102:{manager_name:Emp3,age:45}
}
}
You need to understand that in the representation using cql, is may look like regular relational table, but the internal structure of the rows in Cassandra is completely different. It is saving different set of attributes for each employee, and the nulls you can see while querying with cql is just a representation of empty/nonexistent cells.
What you trying to achieve, is unstructured data model. Cassandra started with this model, and all was working as described in the tutorial you've read, but there is an opinion that unstructured data design is unhealthy to development and makes more problems than it solves. So, after sometime, Cassandra moved to the "structured" data structure (and from thrift to cql). It doesn't mean that you have to store all attributes for all keys/rows, it doesn't mean that all the rows are have same number of attributes, it just means that you have to declare attributes before you use them.
You can achieve some kind of unstructured data modeling using Map, List, Set, etc. data types, UDT (User defined types) or just saving your data as json string and parsing it on the application side.
What you have understood is correct. Just believe it. Internally cassandra stores columns exactly like the image in your question.
Now, what you are expecting is to insert a column which is not defined while creating the Employee table. For dynamic columns, you can always use Map data types .
For example
create table Employee(
empid int primary key,
empName text,
age int,
attributes Map<text,text>);
To add new attributes you can use below queries.
UPDATE Employee SET attributes = { manager_name : Emp3, age:45 } WHERE empid = 102;
Update -
another way to to create a dynamic column model is as below
create table Employee(
empid int primary key,
empName text,
attribute text,
attributevalue text,
primary key (empid,empName,attribute)
);
Lets take few inserts -
insert into Employee (empid,empName,attribute,attributevalue) values (102,'Emp1','age','25') ;
insert into Employee (empid,empName,attribute,attributevalue) values (102,'Emp1','manager','emp2') ;
insert into Employee (empid,empName,attribute,attributevalue) values (102,'Emp1','department','hr') ;
this data structure will create a wide row, and behaves like dynamic column. you can see primary key empid and name is common for all three rows, only attribute and value will change.
Hope this will help
Cassandra uses a special primary key called compositie key. This is the representation of the partitions. This is also one reason why cassandra scales well. The composite key is used to determine the nodes on which the rows are stored.
The result in your console may be a result set of rows, but the intern organization of cassandra is differnt from that. Have you ever tried to query a table without an primary key? You will quickly see that you can't query that flexible (because of the partitioning).
After that you will understand why we have to use a query-first design aproach for cassandra. This is completely different from RDBBS.

Cassandra Hierachy Data Model

I'm newbie design cassandra data model and I need some help to think out the box.
Basically I need a hierarchical table, something pretty standard when talking about Employee.
You have a employee, say Big Boss, that have a list of employee under him.
Something like:
create table employee(id timeuuid, name text, employees list<employee>, primary key(id));
So, is there a way to model a hierarchical model in Cassandra adding the table type itself, or even another approach?
When trying this line above it give me
Bad Request: line 1:61 no viable alternative at input 'employee'
EDITED
I was thinking about 2 possibilities:
Add an uuid instead and in my java application find each uuid Employee when bringing up the "boss".
Working with Map, where the uuid is the id itself and my text would be the entire Row, then in my java application get the maps, convert each "text" employee into a Employee entity and finally return the whole object;
It really depends on your queries...one particular model would only be good for a set of queries, but not others.
You can store ids, and look them up again at the client side. This means n extra queries for each "query". This may or may not be a problem, as queries that hit a partition are fast. Using a map from id to name is also an option. This means you do extra work and denormalise the names into the map values. That's also valid. A third option is to use a UDT (user defined type). You could then have a list or set or even map. In cassandra 2.1, you could index the map keys/ values as well, allowing for some quite flexible querying.
https://www.datastax.com/documentation/cql/3.1/cql/cql_using/cqlUseUDT.html
One more approach could be to store a person's details as id, static columns for their attributes, and have "children" as columns in wide row format.
This could look like
create table person(
id int primary key,
name text static,
age int static,
employees map<int, employeeudt>
);
http://www.datastax.com/documentation/cql/3.1/cql/cql_reference/refStaticCol.html
Querying this will give you rows with the static properties repeated, but on disk, it's still held once. You can resolve the rest client side.

EF5 Navigation/Association Property with non-Primary Foreign Key

This is the same exact question as this, but instead for EF5.
Is it possible now?
We have a Users table that has an int PK, but in our other tables that have columns like InsertBy/UpdateBy, the desire is to use value of the LANID varchar column from the Users table, rather than the UserID.
No it is still not possible. FK must target PK in the principal table because EF still doesn't support unique keys (prerequisite for using non-PK columns).

Simple way to use Foreign Key values for sorting?

Disclaimer: I jumped to C# 2008 recently and SubSonic 3 (3.0.0.4) at the same time. I haven't used Linq for much of anything in the past.
Is there an easy way to use the foreign key display value for sorting, rather than the FK Id (which is numeric)?
I've added a new Find method in my ActiveRecord.tt to help with sorting based on a string field name but after doing some testing I realized that even though its working as it should be, I am not handling foreign key fields at all (they are just sorting by their value).
Even if I need to change how I am accessing the data it is early enough in the project to do that. Just looking for suggestions.
LINQ is your friend in this situation, you just need to join your two objects and then sort by the property from your foreign object:
var primaryObjectsSorted =
from primaryObjects in PrimaryObject.All()
join foreignObjects in ForeignObject.All()
on primaryObjects.ForeignId equals foreignObjects.Id
orderby foreignObjects.PropertyYouWantToSortOn
select primaryObjects;
So you have table A which has id of table B as a foreign key and you want to sort table A by the DisplayName column of table B rather than the id of table B?
The only way to achive this is by a join.
SELECT tableA.* FROM tableA INNLER JOIN tableB ORDER BY tableB.DisplayName
In SubSonic2 you can do that, and still be able to update your records if you use the DB.Select(...).ExecuteCollection() method.
I think this should be possible with subsonic3, too.
Howevery, if you don't use the foreign key and the display name is unique, you should just use this value as your foreign key.

Resources