Does a components data have to be passed in from its parent component? Or does a components query allow the data to flow directly to the component?
I can see how a query declares what data a component needs. Does a parent component have to inspect its child component's query to find out what data to pass to it? Why do many of the examples have parent components calling something like (om/get-query ChildComponentClass)?
Yes. The root component is special. All data has to be passed into the root component. To achieve this your root component's query will be a series of joins. Every component's query you have in your application (that has a unique ident) must be represented as a join at the root level. If data is coming into your application it must be coming into the root. It is put there by Om Next, which takes it from your application's app state.
In an Om Next application your components are composed together as a tree. They are related to one another through their queries, specifically by joins.
At runtime the render methods of each component get their props handed down to them from the parent. The component's query will tell you what props to expect. These props are a simple map.
The answers to your questions in order are: yes, no, yes. For that third one the parent is not really inspecting its child component's query so much as already has the data for that query itself as a join, and is handing the data down to the child.
Your last question 'Why do many of the examples have parent components calling something like (om/get-query ChildComponentClass)?'. This is a join from the parent to the child, described in query syntax:
{:app/child-join (om/get-query app/ChildComponentClass)}
The cardinality of these joins is not known until runtime: it can be 0, 1 or many. If it is one then you might describe it as a lookup relationship. If more than one as a master-detail relationship. If none it could be either.
Related
This question aims to get the most clean and "best" way to handle this kind of problem.
I've read many questions about how to handle inheritance in SQL and like the Table Per Type model most and would like to use it. The problem with this is that you have to know what type you are going to query to do the proper join.
Let's say we have three tables:Son, Daughter and Child.
This works very well if you for example want to query all daughters. You can simply join the child and get all the information.
What I'm trying to do is to query a Child by ID and get the associated sub class information. What I could do is to add a column Type to the child and select the associated data with a second select, but that does not seem pretty nice. Another way to do it would be to join all sub tables, but that doesn't seem to be that nice either.
Is there an inheritance model to solve this kind of problem in a clean, nice and performant way?
I'm using MySQL btw
Given your detailed definition in the comment with the use case
The Server gets the http request domain.com/randomID.
it becomes apparent, that you have a single ID at hand for which you want to retrieve the attributes of derived entities. For your case, I would recommend to use the LEFT JOIN approach:
SELECT age,
son.id is not null as isSon,
randomColumn,
daughter is not null as isDaughter,
whatEver
FROM child
LEFT JOIN son on child.id = son.id
LETT JOIN daughter on child.id = daughter.id
WHERE
child.id = #yourRandomId
This approach, BTW, stays very close to your current database design and thus you would not have to change much. Yet, you are able to benefit from the storage savings that the improved data model provides.
Besides that, I do not see many chances to do it differently:
You have different columns with different datatypes (esp. if looking at your use case), so it is not possible to reduce the number of columns by combining some of them.
Introducing a type attribute is already rejected in your question; sending single SELECT statements as well.
In the comment you are stating that you are looking for something like Map<ID, Child> in MySQL. Please note that this java'ish expression is a compile-time expression which gets instantiated during runtime with the corresponding type of the instance. SQL does not know the difference between runtime and compile-time. Thus, there is also no need for such a generic expression. Finally, also please note that in case of your Java program, you also need to analyse (by introspection or usage of instanceof) which type your value instance has -- and that is also a "single-record" activity which you need to perform.
We are using PHP / SQL to build a parts database which will output as a tree structure. After plunging head first into the coding with the nested sets model we realised that we needed to adjust the model to allow for multiple parents.
Effectively, every child can have more than one parent, and every parent can have more than one child, but each node cannot be its own relative.
We want to link a collection of parts (A) to a parent part and create a larger part (B) whilst keeping the original collection (A) in isolation. That part collection (A) could be used in another part tree but any change to part collection (A) would adjust all entitities it exists within.
We modified the nested model with dependency links similar to the adjacency model and an unique tree id for each part which allows for the individual trees to build up from that.
This worked perfectly to link parts but when it came to unlinking parts there were problems.
Part E could be part of Part D and Part C. When Part C is linked to Part B there is no unique route to Part E without traversal which becomes more extensive the larger the tree gets.
Is there a model which is best suited to a parts database such as this? We have looked at the methods in the question title and the potential to hybrid these models but it is not immediately clear which method or combination will suit this purpose.
Any input greatly appreciated. Thanks.
I have a User model that can hold 1-n UserGroup models, each of which holds data about the user's relationship with a specific group (for example, if they're the admin of the group, when they joined the group, etc.).
I'd like to provide some helper methods like isGroupUser() and isGroupAdmin() that work on the entire set of UserGroup models stored in a User model. Right now these methods are in the User model, but they just about double the size of the model.
Does it make sense to push the code that works on the UserGroup models into its own class? So then the User model would contain a single instance of this "interface" class, which would also now contain the UserGroup models to work on. I feel like this keeps related code nicely separated and the User model from becoming overwhelming.
Also, is there a design pattern for this sort of thing? It seems like a class that works on a collection of other objects would be pretty common.
Thanks for your insight!
Iterator: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. [GoF, p257]
Visitor: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. [GoF, p331]
If you are new to design patterns a quick overview is available at http://www.vincehuston.org/dp/
I suppose the other big benefit of doing it that way pushes all of this UserAccessControl or UserPermissions into a nice reusable setting or object.
I have a question related to this one. I don't want to do a calculation (aggregation), but I need to get display values from an association. In my C# code, I can directly reference the value, because the foreign key constraint made Linq generate all the necessary wiring.
When I specify the IQueryable as the Gridview datasource property, and reference something that is not a column of the primary entity in the result set, I get an error that the column does not exist.
As a newbie to Linq, I am guessing the assignment implicitely converts the IQueryable to a list, and the associations are lost.
My question is, what is a good way to do this?
I assume that I can work around this by writing a parallel query returning an anonymous type that contains all the columns that I need for the gridview. It seems that by doing that I would hold data in memory redundantly that I already have. Can I query the in-memory data structures on the fly when assigning the data source? Or is there a more direct solution?
The gridview is supposed to display the physician's medical group associations, and the name of the association is in a lookup table.
IQueryable<Physician> ph =
from phys in db.Physicians
//from name in phys.PhysicianNames.DefaultIfEmpty()
//from lic in phys.PhysicianLicenseNums.DefaultIfEmpty()
//from addr in phys.PhysicianAddresses.DefaultIfEmpty()
//from npi in phys.PhysicianNPIs.DefaultIfEmpty()
//from assoc in phys.PhysicianMedGroups.DefaultIfEmpty()
where phys.BQID == bqid
select phys;
(source: heeroz.com)
So, based on Denis' answer, I removed all the unneeded stuff from my query. I figured that I may not be asking the right question to begin with.
Anyways, the page shows a physician's data. I want to display all medical group affiliations in a grid (and let the user insert, edit, and update affiliations). I now realize that I don't need to explicitly join in these other tables - Linq does that for me. I can access the license number, which is in a separate table, by referencing it through the chain of child associations.
I cannot reference the medical group name in the gridview, which brings me back to my question:
AffiliationGrid.DataSource = ph.First().PhysicianMedGroups;
This does not work, because med_group_print_name is not accessible for the GridView:
A field or property with the name 'med_group_print_name' was not found on the
selected data source.
Again, bear with me, if it is all too obvious that I don't understand Linq ... because I don't.
Your query seems strange. You should try to simply display
ph = from phys in db.Physicians
where phys.BQID == bqid
select phys;
in your grid. That should work.
Also, why the calls to Load()? If the DataContext is not disposed when the grid is binding, you should not need it.
If you still have issues, can you please post the error message you get, that would help...
Part 2
The problem is that you have the name is effectively not in the PhysMedGroup. You need to navigate one level down to the MedGroupLookup to access the name, since it is a property of that class.
Depending on the technology you are using (it seems to be either WinForms or Web Forms), you will need to configure your data-binding to access MedGroupLookup.med_group_print_name.
I am trying to inherit from my generated datacontext in LinqToSQL - something like this
public class myContext : dbDataContext {
public System.Data.Linq.Table<User>() Users {
return (from x in base.Users() where x.DeletedOn.HasValue == false select x);
}
}
But my Linq statement returns IQueryable which cannot cast to Table - does anyone know a way to limit the contents of a Linq.Table - I am trying to be certain that anywhere my Users table is accessed, it doesn't return those marked deleted. Perhaps I am going about this all wrong - any suggestions would be greatly appreciated.
Hal
Another approach would to be use views..
CREATE VIEW ActiveUsers as SELECT * FROM Users WHERE IsDeleted = 0
As far as linq to sql is concerned, that is just the same as a table. For any table that you needed the DeletedOn filtering, just create a view that uses the filter and use that in place of the table in your data context.
You could use discriminator column inheritance on the table, ie. a DeletedUsers table and ActiveUsers table where the discriminator column says which goes to which. Then in your code, just reference the Users.OfType ActiveUsers, which will never include anything deleted.
As a side note, how the heck do you do this with markdown?
Users.OfType<ActiveUsers>
I can get it in code, but not inline
Encapsulate your DataContext so that developers don't use Table in their queries. I have an 'All' property on my repositories that does a similar filtering to what you need. So then queries are like:
from item in All
where ...
select item
and all might be:
public IQueryable<T> All
{
get { return MyDataContext.GetTable<T>.Where(entity => !entity.DeletedOn.HasValue); }
}
You can use a stored procedure that returns all the mapped columns in the table for all the records that are not marked deleted, then map the LINQ to SQL class to the stored procedure's results. I think you just drag-drop the stored proc in Server Explorer on to the class in the LINQ to SQL designer.
What I did in this circumstance is I created a repository class that passes back IQueryable but basically is just
from t in _db.Table
select t;
this is usually referenced by tableRepository.GetAllXXX(); but you could have a tableRepository.GetAllNonDeletedXXX(); that puts in that preliminary where clause to take out the deleted rows. This would allow you to get back the deleted ones, the undeleted ones and all rows using different methods.
Perhaps my comment to Keven sheffield's response may shed some light on what I am trying to accomplish:
I have a similar repository for most
of my data access, but I am trying to
be able to traverse my relationships
and maintain the DeletedOn logic,
without actually calling any
additional methods. The objects are
interrogated (spelling fixed) by a StringTemplate
processor which can't call methods
(just props/fields).
I will ultimately need this DeletedOn filtering for all of the tables in my application. The inherited class solution from Scott Nichols should work (although I will need to derive a class and relationships for around 30 tables - ouch), although I need to figure out how to check for a null value in my Derived Class Discriminator Value property.
I may just end up extended all my classes specifically for the StringTemplate processing, explicitly adding properties for the relationships I need, I would just love to be able to throw StringTemplate a [user] and have it walk through everything.
There are a couple of views we use in associations and they still appear just like any other relationship. We did need to add the associations manually. The only thing I can think to suggest is to take a look at the properties and decorated attributes generated for those classes and associations.
Add a couple tables that have the same relationship and compare those to the view that isn't showing up.
Also, sometimes the refresh on the server explorer connection doesn't seem to work correctly and the entities aren't created correctly initially, unless we remove them from the designer, close the project, then reopen the project and add them again from the server explorer. This is assuming you are using Visual Studio 2008 with the linq to sql .dbml designer.
I found the problem that I had with the relationships/associations not showing in the views. It seems that you have to go through each class in the dbml and set a primary key for views as it is unable to extract that information from the schema. I am in the process of setting the primary keys now and am planning to go the view route to isolate only non-deleted items.
Thanks and I will update more later.