This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I am in the process of evaluating LightSpeed and so far I have to say that I am very impressed with the simplicity and speed of your product. I am wondering though if there is a way of getting a flattened list of the entities in an entity graph given a list of root entities and the relations you would like to traverse. Alternatively, I could see passing the root entities and a named aggregate and getting back a list of all the entities in the graph. I imagine I could build something using reflection to do this, but I am wondering if there is a better way. For example, lets say that I have a form for editing an Order and its associated entities. An Order has multiple OrderItems, Notes and Shipments. I want to quickly tell if any of the of the entities that make up a complete order have been modified. I want to also be careful not get Entity or EntityCollection properties that have not been loaded yet (IsLazy) because there is no reason to load these enties just to tell if something has changed. I could see having a function that looked something like this that might work: Entity[] FindEntitiesInGraph(IEnumerable<Entity> rootEntities, string aggregateName, Func<Entity, bool> predicate) I could then use it as follows: var modifiedEntities = FindEntitiesInGraph(new [] { order }, "WholeOrder", e => e.EntityState != EntityState.Default); Of course, I could also see having additional arguments for specifying whether to load child EntityCollections, etc. I could also see having another way to specify the set of relations to traverse when building this entity graph besides named aggregates. I guess this could also be made into an extension method. Is there some way to only query the entities that are already in memory and return a none-heterogeneous list of related entities? Am I missing something obvious or is this the kind of thing we need to build ourselves? Thanks, Neal Borelli |
|
|
We don't directly provide a way to query only the entities that are already in memory, or to return a heterogeneous list of related entities. As you say, such a thing could be built using reflection; you could also do it in a less generic manner by adding navigation and aggregation functions to the relevant domain classes (you can do this via a partial class if you are using the designer). As a suggestion, I would consider building your function to return an object graph of modified objects, rather than a flattened list. You could then flatten it as a separate step. The reason for suggesting this is that if you wanted to present the modified list in a UI ("The following items will be saved:") then you may want to preserve the hierarchy (for example, which OrderItems belong to which Orders) in the display. This suggests specialised properties on the classes such as Order.ModifiedOrderItems which would return an empty sequence if _orderItems was unloaded or _orderItems.Where(oi => oi.EntityState != EntityState.Default) if _orderItems was loaded. Obviously this depends on the use cases though. |
|
|
Thanks for the tips Ivan. I have one other question though. If I wanted to do this in a sort of generic fashion using reflection, how can I look at a parent relationship property without causing it to be lazy loaded. For example, lets say I have an Order entity that has a Customer property. The property is backed by a field of type EntityHolder<Customer>, but the public property is exposed as public Customer Customer. Is there a good way for me to check the IsLazy property of the backing EntityHolder? Do I have to reflect on the private fields to get the EntityHolder? At this point, I am just trying to determine if a save is needed so that I can enable teh save command in our UI. -Neal
|
|
|
You would need to check the IsLazy property of the backing EntityHolder or EntityCollection field. (Note that even though collection properties are of type EntityCollection, performing a get of the property always triggers the load. So you would still need to use the backing field rather than the property.) So yes, you would need either to reflect on the private fields, or to create class-specific methods or properties which access those private fields. |
|
|
I would like to add that it would be helpful if the Value property of the EntityHolder class or the whole IEntityHolder interface was made public. Right now it seams hard to get the Value from an EntityHolder only if IsLazy is false. I am using reflection to look at the backing fields and cannot easily match them to their corresponding properties without making assumptions about how the code will be generated. Since this is an extension method, I cannot call the protected Get<TEntity>(EntityHolder<TEntity>) method on the Entity class. -Neal |
|
|
Thanks for the comment -- now that .NET 3.5 / C# 3 is well entrenched it would probably for us to generally have a look at what we can do to make entities easier to work with from extension methods (as opposed to the .NET 2.0 partial class/base class approach), e.g. making some of the protected methods public. I've logged a feature request for this. |
|