I'm using a NSFetchedResultsController to implement KVO for my UITableView (which is obvious). What I can't figure out is, how to use multiple Entities - sort of a tree structure - to be present(ed) simultaneously.
Here is my setup:
Entity1
DisplayName
RelationToEntity2
Entity2
DisplayName
Now I can fetch the data of either to be presented - so far so good. What I want is to have a one-sectioned TableView (like a flattened view) with the following structure:
Entity1 (Entry 1)
Entity2 (Entry 1)
Entity2 (Entry 2)
…
Entity1 (Entry 2)
…
Though it might look like a thing to be done via sections, it's not. Both Entities should be a UITableViewCells. Can someone please point me the right direction to flatten the without loosing the actual hierarchy.
It sounds like you need to maintain your own 'flattened' datasource. Perhaps the following will work:
When NSFetchedResultController tells you a new Entity1 has been inserted, you insert Entity1 and its associated Entity2s into say, _flattenedArray so it looks like this:
[<Entity1>, <related Entity2>, <related Entity2>...]
Where you insert them is up to you - it pretty much comes down to:
construct a subarray containing the new Entity1 and associated Entity2 objects
decide where in _flattenedArray to insert the new subarray.
call reloadData or some other means to inform the tableView of the new data
When an Entity1 object is removed, remove it and all subsequent Entity2 objects until you encounter the end of _flattenedArray or run into another Entity1 object. This assumes Entity2 is never a "top level" object. If it is you will need to only remove those Entity2 objects in the relation.
When an Entity1 object gains or loses an Entity2 object, you can first delete the Entity1 object from _flattenedArray then reinserting it. If this is too efficient, do a merge instead.
This is exactly the situation to use entity inheritance. When fetching a parent abstract entity with a fetched results controller all of the child entities can be displayed by the table. Use a section order property to display the sections in the order you prefer. And use a second sort property to order within the sections. The Notes app does this by fetching an abstract Container entity and displays Accounts and Folders which are child entities. It sections by Account and the first folder "All iCloud" cell is actually an Account. Folders have a relation to an account even though they are equals in the entity inheritance tree.
Related
Im pretty new to nhibernate so this may be quite straightforward but i havent found an answer on the web yet.
Lets say i have a Parent class and a Child class. The Parent Class can have many Child classes associated with it. Now when i try to load a specific Parent nhibernate also populates its Child collection for me. There are situations where I want to just return a Parent class without a Child collection.
I know i can turn on Lazy loading but that wont work as im serializing the Parent to XML. The XML serialiser cannot work with the nhibernate PersistanceBag that contains the Child collection.
So is there a way to define a Parent class, lets say ParentView which works on the same table but only contains the Parent properties and not all its children and grandchildren?
Define a class ParentView that contains the columns you need to retrieve. Make sure this class has one parameterless constructor.
ISession session = NHibernateHelper.Session;
ISQLQuery query = session.CreateSQLQuery("select Parent_ID, Name form Parent where Parent_ID = :parentID");
query.SetInt32("parentID", parentID);
IList<ParentView> parentView = query.SetResultTransformer(Transformers.AliasToBean<ParentView>()).List<ParentView>();
return parentView;
An alternative to creating a view class and associated query as suggested by sh_kamalh (which I would consider if I were you). If the problem is related to the bag mapping structure specifically then you might have a couple of easier solutions:
Option 1
Revisit the bag mapping - Maybe simple selecting a different strategy will fix the issue. I have answered a question on the different collection mappings before List vs Set vs Bag in NHibernate personally I find that I use the Set strategy a lot. To map a different strategy in Fluent NHibernate use the following as a guide in your override.
mapping.HasMany<Child>(x => x.Children).ToSet();
or
mapping.HasMany<Child>(x => x.Children).ToList();
Option 2
Not particularly related to NHibernate but if you are using the default xml serializer you might be able to tell the xml serializer to simply ignore that property and leave the bag mapping in place.
[System.Xml.Serialization.XmlIgnore]
public IEnumerable<Child> Children { get; internal set; }
I am looking for some reference work or tutorial of a persistent objective-c tree? I am trying to build a family tree (genealogy records) app on iPhone / Mac OS. Thanks!
(key: --> = to-one, -->> = to-many)
Your basic tree-like entity map would look like this:
LinkedTreeNode{
//... whatever attributes you want a node to have
parent <--(optional,nullify)-->>LinkedTreeNode.children
children <<--(optional, cascade)-->LinkedTreeNode.parent
}
It has one entity that has relationships to itself. The parent relationship points to one other object above it in the tree (the parent) and to one or more child objects below it in the tree. Its logically exactly like a standard C tree. You simply replace pointers that serve as links with entity graph relationships.
For modeling genealogy relationships, you need to add a spouse because (hopefully) every person as a father and mother and any person may have more than one spouse.
Person{
spouses <<--(optional,nullify)-->>Person.spouses
parents <<--(optional,nullify,Max=2)-->>Person.children
children <<--(optional,cascade)-->>Person.parents
}
NHibernate question:
Say I have a SQL table Person and it has a Picture column ( OLE Object ) . I have a class Person and it has : byte[] Picture attribute.
Is it possible to map like this ?
<property name = "Picture" column = "Picture" type = "System.Byte[]" lazy="true" />
Does the "lazy" keyword have any effect on properties or can it only be used when working with collections / bags etc?
It appears that this feature just landed in the NHibernate trunk:
http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx
I have not found any way to get this to work, but the following two ways may help you around the problem you imply:
You can map two classes for the same table, one including the byte array, the other not.
You can include a many-to-one property mapping to the same table, where the child class has the byte array included, and you then access the binary using Person.PersonPicture.Picture rather than just Person.Picture; the intermediate class can now be lazy loaded.
Neither is ideal, but they do work. Short answer - collections and many-to-one properties can be lazy loaded, straight properties not.
I have and entity lets call it Entity, and a Child collection Children.
I have a screen where the user has the Entity information, and a list with the Children collection, but that collection can be get very big, so i was thinking about using paging: get the first 20 elements, and lazy load the next only if the user explicitly presses the next button.
So i created in the Entity Repository a function with this signature:
IEnumerable<Child> GetChildren(Entity entity, int actualPage, int numberOfRecordsPerPage)
I need to use the setfirstresult and setmaxresult, not in the Agregate root Entity, but in the child collection. But when i use those two configurations, they allways refer to the entity type of the HQL/Criteria query.
Other alternative would be to create a HQL/Criteria query for the Child type, set the max and first result, then filter the ones who are in the Entity Children collection (by using subquery).
But i wasn't able to do this filter. If it was a bidirectional association (Child refering the parent Entity) it would be easier.
Any suggestions?
Any
One approach would be to create a query that returns results from both tables by doing a group by. This approach would allow you to apply paging on data that will come from the children collection and have a common factor (the entity's ID in each row) while you keep your starting point (the Entity object). What I mean is something like that:
public IList<object> GetData(int entityID, int actualPage, int numberOfRecordsPerPage)
{
ICriteria criteria = _repository.Session.CreateCriteria<FlowWhatIfProfile>("entity")
.CreateCriteria("Children", "children", NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(Restrictions.Eq("children.EntityID", entityID));
ProjectionList pl = Projections.ProjectionList();
pl.Add(Projections.GroupProperty("children.Id"));
pl.Add(Projections.GroupProperty("children.Property1"));
pl.Add(Projections.GroupProperty("children.Property2"));
pl.Add(Projections.GroupProperty("children.Property2"));
pl.Add(Projections.GroupProperty("entity.Id"));
return criteria.SetProjection(pl)
.SetFirstResult(actualPage * numberOfRecordsPerPage)
.SetFetchSize(numberOfRecordsPerPage)
.List<object>();
}
The drawback would be that your returned data are a list of arrays (you will have to cast object to object[]) but you can overcome that by using the AliasToBean functionality that lest NHibernate project these arrays to strongly typed objects that you define.
it's simple with CreateFilter
session.CreateFilter(entity.children, "")
.SetFirstResult(0)
.SetMaxResults(20)
.List();
http://knol.google.com/k/fabio-maulo/nhibernate-chapter-16/1nr4enxv3dpeq/19#
I'm looking for way in Fluent NHibernate to get a list of all object of type PARENT
using criteria.
I have a father object and a derived child.
The father contains a list of childs.
The problem is that when I use:
ICriteria crit = session.CreateCriteria(typeof(Parent))
IList<Parent> myRes = crit.List<Parnet>()
NH return back the list of both parent elements and the derived children elements, which is "right" b/c that is what I've asked, but that is not what I need.
(the children elements should be only inside the father object, but since they are of type parent as well - since they derived from it... NH brings them as well using this method.)
How can I get the list of all my "father" elements without the derived children ?
This is from the first answer (#Stefan Steinegger's)
session
.CreateQuery("from Parent where Parent.class == :class")
.AddType(typeof(Parent));
It looks like I need something like that - but it doesn't work in Fluent NHibernate.
Thanks,
Dani
the question actually is: how do you determine if a Parent is a root parent? there are various approaches:
You keep your model and define: a root is a Parent that is not inherited and is not included in any other Parent.
The part "is not inherited" might be easy to determine, but is actually a poor definition. When using inheritance, you should actually not care if an object you get as a certain type is actually inherited or not, this is the nature of inheritance.
The part "is not included in any other Parent" is hard to find out in an efficient way.
You set a reference to an objects parent. A root is a Parent where its parent references null.
You derive your Root from a common Base class. A Child is not a Root anymore, and a Root is a Root.
I suggest to take the last option.
BTW: you can filter for the exact type, but only using HQL.
session
.CreateQuery("from Parent where Parent.class == :class")
.AddType(typeof(Parent));