I have the AdminFiles entity which holds files for all project entities (news, pages, events etc.). It is structured (abridged) like this:
id int(11) Auto Increment
entity varchar(255) // this holds the entity name, e.g. Page or News
entity_id int(11) NULL // this holds the entity ID
filename varchar(1000) // this holds the path to the file
I would love to access the files in the entities (Page, News etc.) with something like $entity->getFiles(). But I'm having trouble creating the relation, since it is not only constrained by the ID, but also the entity name. Is there any way to join this inside the Doctrine2 entity, or do I have to do this in the service?
This can be handled by Doctrine by using discriminator map feature. In your case there will be multiple entities inherited from base AdminFiles entity, each one will be specific for single type of files (e.g. PageFiles, NewsFiles and so on). You will need to establish mapping between entity column and these entities into #DiscriminatorMap annotation, then you will be able to fetch just one particular type of file by fetching (or using in association mapping) entity that represents some specific type of file.
You will also be able to even have entity properties that are specific to some particular type of file by using this feature.
Related
We can add page relationship in two different ways using named relationships and pages data type which is kind of advanced content modelling in Kentico..
if we go through named relationships then we can give a meaningful relationship between to content node by providing description. So, we get a relationship name called “is related to”(example). When we use this in practice, then we get [page A] {is related to} [Page B].
if we go through pages data type then we assign some content on the form tab, records are created in the “CMS_Relationship” table as ad-hoc via the “RelationshipIsAdHoc” column and there is no relationship name for this as such. It is marked as Ad-hoc. and Relationship name is also added page type name underscore some randon guid example abc.product_3d628a37-7637-4a21-b0b4-e1dd1a00a3bc
My question is when we try to use page data type and we need to add relationship through api code, then how can we add because in kentico api to add page relationship through api code RelationShipNameID is mandatory field. We don't have this RelationShipNameID as we are not going through named relationship.
Found out the way
Need to retrieve ad-hoc relatioshipnameinfo object, e.g. like this:
string codeName = GetAdHocRelationshipNameCodeName("fillclassnamehere", field);
var relationshipNameInfo = GetRelationshipNameInfo(codeName);
and then use is with API:
RelationshipInfoProvider.AddRelationship(leftSiteId, rightSiteId, relationshipNameInfo.RelationshipNameId)
If you leave one or the other empty, or don't specify in your Entity, it creates a key/id for that entity anyways, as seen in the admin console datastore viewer.
Bonus question: Why can't you get the ID for an Entity object after you put() it? entity.getProperty("id") returns null. Key objects cannot be serialized so cannot be used by GWT.
Reference:
https://developers.google.com/appengine/docs/java/datastore/entities
https://developers.google.com/appengine/docs/java/datastore/jdo/creatinggettinganddeletingdata#Keys
Entities have a Key, and Keys (of persisted entities) have either auto-assigned ids, or programmer-supplied names. The name/id is a property of the Key, not a property of the Entity.
Instead of entity.getProperty("id") in Java you write entity.getKey().getId() (or .getName() if you gave the key a name).
The lower-level details are in:
https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Entity
https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/Key
`
OK, I don't know whether this question belong to this place, but you will suggest me if I'm wrong.
I have some entities which has almost same attributes, differences is in maybe 2-3 columns.
Because of those different columns, I can't create one table with columns that are union of attributes of every entity, because new entity type will require changing table design adding new columns specific to that entity type.
Instead, currently working design is that every specific entity has own table.
But, if new type of entity come on scene, I must create new table, which is totally bad idea.
How can I create one table which consists shared attributes for each type of entity, and some additional mechanism to evidence entity-unique attributes?
So, idea is to easy add new types of objects, without changing database design, configuring only part that deal with unique columns.
P.S. Maybe I'm not clear, but I will add more description if is it needed.
I had a design like that once. What I did was I created a table that housed all the shared properties. Then, I had separate tables for the distinct values. I used joins to match a specific entity to its shared table row. I had less than 10, so my views that used unions I just updated when I added a new entity. But, if you used a naming convention, you could write stored procs that find the table names dynamically and do the unions and joins on the fly. In my case, I used a base class and specific classes to make a custom data layer.
Another possibility is to have a generic table that's basically name/value pairs and a table the represents your shared properties. By joining the tables together, you could have any number of entity specific properties for your entities. It's not very efficient and the SQL would get weird, but I've seen it done.
One solution is to store the common parts in one table, and the specific parts in tables specific to that entity.
eg: To have a set of people, some of whom are managers...
Person Table
PersonID
PersonName
Manager Table
ManagerID
PersonID
DepartmentManaged
As soon as you go down the path of having one table with variable field meanings - effectively an Entity Attribute Value design - you find yourself in querying hell.
Perhaps not the best or most academic, but what about this kind of "open structure" ?
MainTable: all common fields
SpecialProperties: extra properties, as required
- MainRecordId (P, F->MainTable)
- PropertyName (P)
- PropertyText
- PropertyValue (for numeric values)
I've been thinking about creating a database that, instead of having a table per object I want to represent, would have a series of generic tables that would allow me to represent anything I want and even modifying (that's actually my main interest) the data associated with any kind of object I represent.
As an example, let's say I'm creating a web application that would let people make appointments with hairdressers. What I would usually do is having the following tables in my database :
clients
hairdressers: FK: id of the company the hairdresser works for
companies
appointments: FK: id of the client and the hairdresser for that appointment
But what happens if we deal with scientific hairdressers that want to associate more data to an appointment (e.g. quantity of shampoo used, grams of hair cut, number of scissor's strokes,...) ?
I was thinking instead of that, I could use the following tables:
entity: represents anything I want. PK(entity_id)
group: is an entity (when I create a group, I first create an entity which
id is then referred to by the FK of the group). PK(group_id), FK(entity_id)
entity_group: each group can contain multiple entity (thus also other groups): PK(entity_id, group_id).
role: e.g. Administrator, Client, HairDresser, Company. PK(role_id)
entity_role: each entity can have multiple roles: PK(entity_id, role_id)
metadata: contains the name and type of the metadata aswell as the associated role and a flag that describes if its mandatory or not. PK(metadata_id), FK(metadata_type_id, role_id)
metadata_type: contains information about available metadata types. PK(metadata_type_id)
metadata_value: PK(metadata_value_id), FK(metadata_id)
metadata_: different tables for the different types e.g. char, text, integer, double, datetime, date. PK(metadata__id), FK(metadata_value_id) which contain the actual value of a metadata associated with an entity.
entity_metadata: contains data associated with an entity e.g. name of a client, address of a company,... PK(entity_id, metadata_value_id). Using the type of the metadata, its possible to select the actual value of a metadata for this entity in the corresponding table.
This would allow me to have a completely flexible data structure but has a few drawbacks:
Selecting the metadatas associated with an entity returns multiple rows that I have to process in my code to create the representation of the entity in my code.
Selecting metadatas of multiple entities requires to loop over the same process as above.
Selecting metadatas will also require me to do a select for each one of the metadata_* table that I have.
On the other hand, it has some advantages. For example, instead of having a client table with a lot of fields that will almost never be filled, I just use the exact number of rows that I need.
Is this a good idea at all?
I hope that I've expressed clearly what I'm trying to achieve. I guess that I'm not the first one who wonders how to achieve that but I was not able to find the right keywords to find an answer to that question :/
Thanks!
I have many entities of one type which have Key with auto-generated Long ID (e.g. Person(1234)), but now I need to change those keys to have String name instead (e.g. Person("username")).
How should I achieve this?
You have two options:
Add a username attribute to the entity and get (using query) the entity by user name.
When creating the Person entity provide a key_name (Person(key_name=username, ...) ), but you will need to migrate all the existing Person entities by recreating them.
Once an entity has been saved to the datastore, it's key cannot be changed. So you'll either have to make do with the existing keys, or create new entities with the new keys and remap any existing pointers to the original entities.