New Posts New Posts RSS Feed: child viewmodel entity query
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

child viewmodel entity query

 Post Reply Post Reply
Author
bigfish View Drop Down
Newbie
Newbie


Joined: 20-Mar-2009
Location: Australia
Posts: 36
Post Options Post Options   Quote bigfish Quote  Post ReplyReply Direct Link To This Post Topic: child viewmodel entity query
    Posted: 16-Sep-2009 at 3:04pm

I have a child view/viewmodel that issues an entity query. 

The child view is instantiated from an EDIT function from its parent view, grid row (identical to your Prism Explorer actually).
 
The child viewmodel entity query is used to populate a combobox. 
 
As such, the entity query needs to return a collection of all records from the datasource. 
 
Currently it acts as if its a navigation query, returning only a collection that is constrained (filtered) by the parent row. 
 
There is a database constraint in place.  Parent table FK id is dependant on valid PK values from child table.
 
Is it possible to override or avoid this constraint in the query mechanism? I want the child view/viewmodel to provision a collection of all child table values, regardless of the parent table FK value. 
 
I've tried to issue various querystrategies to avoid this with no joy. In fact the Entity Manager does not even perform a query if a querystrategy.datasourceonly (or other) is included, I think becasue it realises its going to only perfrom navigation query, so ignores it altogether as an invalid query construct.
 
The same query works fine and returns expected results if I plug it into Prism Explorer QueryRepository.  There, there is no constraint from a parent row.
 
Also, none of the queries from the child viewmodel end up in the debug log.  Is this because its a navigation query, not entity query?
 
Thanks if you can help.
Rgds
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 17-Sep-2009 at 12:17pm
The entity with the foreign key is the child.  Suppose, for example, that you have an Order entity that belongs to a Customer. A Customer can have many Orders, but each Order has only one Customer.  Order is the child in the relationship; Customer the Parent. In the database, Order has a foreign key pointing to a particular Customer record.

It sounds like you want to pick a parent from your ComboBox; e.g., while viewing the details of an Order, you want to assign a Customer to be the owner of that Order.

The ItemsSource for your customer ComboBox needs to be a collection that includes all Customers. You will never get that collection from the Customer navigation property of Order.  You should get it from an independent query like
    
        List<Customer> customers = entityManager.Customers



Back to Top
bigfish View Drop Down
Newbie
Newbie


Joined: 20-Mar-2009
Location: Australia
Posts: 36
Post Options Post Options   Quote bigfish Quote  Post ReplyReply Direct Link To This Post Posted: 17-Sep-2009 at 1:38pm
Thanks Greg, I think I was not very clear in my post.
The relationship in the database is so:
 
 
 
The application exposes a house(property) and its assets:
 
 
Editing one row (one asset) at a time exposes a Child window:
 
In that child Window collection of AssetComponents is needed and while the attempt to gather these via the following query is made, only a single value is returned:  that of the parent Asset row....  I think EM is doing navigation query, not entity query.
 
public void GetAssetComponents(Action<IEnumerable> callback) {
IEntityQuery<AssetComponent> assetComponentQuery = Manager.AssetComponents
.Include("AssetType")
.Include("AssetZone");
 
Manager.ExecuteQueryAsync(assetComponentQuery, args => callbackAssetComponent(args, callback), null);
 }
 
This query is issued from the child window's viewmodel.  The child window has on it a dataform, current item set to the current selected asset.
 
Further help to overcome this will be very much appreciated.
 
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 18-Sep-2009 at 9:08am
Bigfish:

Can you please specify which columns are foreign keys for each of the relationships? Since the naming conventions are not very regular, I'd rather not guess.
Back to Top
bigfish View Drop Down
Newbie
Newbie


Joined: 20-Mar-2009
Location: Australia
Posts: 36
Post Options Post Options   Quote bigfish Quote  Post ReplyReply Direct Link To This Post Posted: 18-Sep-2009 at 11:46am
Hi Greg, thanks.
 
the main PK/FK relationship of concern here is the one between Asset and AssetComponent.
 
Asset.assetComponentID(int)(fk) -> AssetComponent.assetComponentID(int)(pk)
 
Asset.propertyID(int)(fk) -> Property.propertyID(int)(pk)
 
AssetComponent.assetTypeID(int)(fk) -> AllType.allTypeID(int)(pk)
AssetComponent.assetZoneID(int)(fk) -> AllType.allTypeID(int)(pk)
 
These ones are likely irrelevant for the problem at hand but exist nonetheless
Property.councilTypeID(int)(fk) -> AllType.allTypeID(int)(pk)
Property.propertySourceID(int)(fk) -> AllType.allTypeID(int)(pk)
Property.areaTypeID(int)(fk) -> AllType.allTypeID(int)(pk)
Back to Top
bigfish View Drop Down
Newbie
Newbie


Joined: 20-Mar-2009
Location: Australia
Posts: 36
Post Options Post Options   Quote bigfish Quote  Post ReplyReply Direct Link To This Post Posted: 21-Sep-2009 at 9:14pm
Hi Greg, any further thoughts on this please?
 
While I've played around with it a lot, still no luck from my end.
 
I've created a view of the AssetComponent table, no relationship constraints therefore, but in this case zero rows are returned.  I suspect that the Dataform Control on the ChildUserControl limits the child viewmodel query to only those of the dataform's currentitem....  ie the scope is being constrained in the binding mechanism before the IB query can be fired.
 
The code used to call the form (same as in Prism Explorer) is:
 

public void EditAsset()

{

var viewModel = new AssetViewModel(QueryRepository) {SelectedAsset = SelectedAsset };

var assetView = new AssetView(viewModel);

assetView.Show();

}

 
I suspect I will need to generate the AssetComponent collection prior to this method, and pass it in as part of the constructor as is the SelectedAsset above if I am to avoid the IB query being constrained (if that is what is happening). 
 
Your thoughts please?
 
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 22-Sep-2009 at 9:44am
Sorry, bigfish, I've just sort of gotten lost in the trees in this one. Have you been able successfully to wire up a simple ComboBox in a Silverlight DataGrid, with nothing else going on?
Back to Top
GregD View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 374
Post Options Post Options   Quote GregD Quote  Post ReplyReply Direct Link To This Post Posted: 22-Sep-2009 at 9:57am
Oh, wait, sorry, I see from your picture that your ComboBox is on a DataForm rather than a DataGrid. But in any event, the MainFormIntermediate in the FourSimpleSteps tutorial solution in the LearningResources uses a ComboBox for the editing template of an Orders grid column that shows the selected Order's parent Customer. To activate the editing template, the user has to double-click in the Customer column. All Customers in the database are available in the item list, but the cell is bound to a single Customer at any given time.

That one is in a grid, but the basic wiring and population of the Combobox are the same in a DataForm. Perhaps you can look at how the ComboBox is configured there, and tell me if there's anything substantially different about your situation.


Back to Top
bigfish View Drop Down
Newbie
Newbie


Joined: 20-Mar-2009
Location: Australia
Posts: 36
Post Options Post Options   Quote bigfish Quote  Post ReplyReply Direct Link To This Post Posted: 01-Oct-2009 at 12:17pm

Hi Greg, finally got back to this with some details that make more sense.  Firstly, thanks for pointing out FourSimpleSteps sample, that provided some insight and now I can get it to work.
 
In your sample, you have wired up the code behind.  You have created a CustomerList class.  You got a handle to the DomainModelEntityManager for second time within that class via a new login which I think is the key here.  From memory you're using IList and binding the combobox to Name(string) properties on both sides.
 
In my situation I need to use IDictionary, swapping Name properties with FK ids of Int32 datatypes which imposes more complication around the binding manager, data context of the dataform and associated viewmodel (in prism) and also dataconverters to facilitate matching Int32 values with valid key/value pairs in the combobox dictionary. For storage and retrieval performance of course.
 
That complication being said, I created the Dictionary as a public property of the viewmodel associated with the view, not a separate class altogether as in your sample.  This approach made it simpler for binding manager to use a DataContextProxy to assist navigating the viewmodel properties.
 
The upshot of your sample and the winning formula was the declaration to get another handle to the DomainModelEntityManager within the CustomerList class.  Essentially, this enables a query to be run with is an EntityQuery within its own context, not (it seems) filtered by its parent.  In my earlier post I was suspecting DF was doing NavigationQuery.

As a result, I have amended my code to use a NEW  DomainModelEntityManager instance in each instantiation of the viewmodel, and now my combobox populates as I need.

However, is this the right thing to do architecturally.  I fear scalability will be severely impacted here.  As I construct a new child form to edit row details, a new instance of DomainModelEntityManager is created.  20 edits, 20 new instances as evidenced in the log file as UserName = Default Principal - 1, 2, 3, 4 etc.

Your FourSimpleSteps code uses DomainModelEntityManager manager = DomainModelEntityManager.DefaultManager - which is not a new instance, but a separate login is used.

If I use .DefaultManager, it's the same as using the current dmem instance I have already, so it won't work.  I have to use = new DomainModelEntityManager(); each time to overcome NavigationQuery issues I've mentioned.

Can you shed some more light on whether I should use this approach, or if there is some other way I can use the same single DomainModelEntityManager instance throughout the entire application yet provide ability to choose whether an Entity Query works in the context of NavigationQuery OR full EntityQuery unencumbered with its navigation neighbors.
 

Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down