How to represent 1-to-many relationship in as3.0 data model - database

I'm building an AS3.0 model for reading from an sqlite database. I've successfully got it working with a simple table. Basically I have a databasemodel class with some shared functions and from it I extend classes, theoretically for each table on the database, but also for 'views' ie combinations of data on different tables when I need to mix things up.
Some of the events have tags stored in a separate table, and I'm wondering about the best way to handle those.. should I include an array in the event class and work with it that way, or separate each tag/cluster of tags into their own class? The tags are predefined and will be edited basically in the same places as if just another property of the event. However many events are imported and can only be edited by changing the tags.

Related

Persisting and rejecting changes to different levels of a hierarchical association - Extjs 5/Sencha

I'm facing a very critical issue where I can't persist my data to the server.
I am building a dashboard where the user can create new dashboards and customize existing ones. A dashboard layout will have one or more rows. Each row contains one or more cells which vary in width. Each cell will have one or more widget instances where it holds a reference to a particular widget. So you have data about widgets in another table. And I'm using table storage.
So I have the tables as follow.
Page, PageLayout, Row, Cell, CellWidgetInstance
Widget, WidgetInstance
So I have models for all the above tables and added a store for getting a particular page layout.
Page HasMany PageLayout
PageLayout HasMany Row
Row HasMany Cell
Cell HasMany CellWidgetInstance
CellWidgetInstance HasOne WidgetInstance
WidgetInstance HasOne Widget
So I can build the entire view or the edit view modes of the page using the pageLayout returned from the store. So I can access to the Rows collection and go on to the lower levels.
Now the problem comes when I'm trying to save the changes. In the edit view user can add/remove rows, add/remove/update cells, add/remove WidgetInstances etc.
And if the user wishes to click cancel after doing all these changes it should not go to the server and I should be able to reject all the changes in different levels. And if the user wishes to save I should be able to save all the changes in one transaction.
I hoped by adding all the necessary CUD (create/update/delete) proxies to the models, doing pageLayoutStore.sync() and pageLayoutStore.rejectChanges() would do the trick calling each model's create/update/delete urls as per the changes. But it seems although sencha supports retrieving the whole hierarchy it does not support saving as a hierarchy still.
So I'm now hitting a major blocker where I can implement the functionality I needed which is a very standard functionality in most cases. Saving/rejecting models and associated models.
I spent hours searching the web and the sencha forums and all they say is sencha still does not support saving associated data. And in one case there was a work around to save the models then and there without using the store. But in my case I can't do this as the user might cancel after editing.
Can anybody suggest a work around for this?
Many Thanks,
Dushan
You're absolutely right - Sencha does not support saving a nested document.
There are a few workarounds. The simplest one is to use the 'auto' type, at the top level, and give up the power of models the rest of the way down.
A slightly more complex version is to use a custom writer to your PageLayout class, so that it can construct the data to be sent by hand; this will give you full control, and allow you to save your models at the PageLayout level.
It's also possible to extend Model to allow for additional association types - I've done this for my current project, but it's somewhat complex (and, no, I'm not in a position to share it at this time). If you've only got one "top-level model" to save in this nested fashion, then the custom writer is the easiest.

Reusing WPF MVVM Views

I've inherited an application which uses the view-first MVVMC patern
In the application I've created 2 step process which creates a person and assigns them to a group. To do this I've created a view and corresponding view model (all views have a 1-2-1 relationship with a view model, view models are injected into the View constructor and are registered with the Unity container using the TransientLifetimeManager) called CreatePersonMaster, the view simply contains a region (shown by the dashed line) which sub-views can be loaded into and the view model subscribes to two loosely coupled events, "PersonCreated" and "GroupSelected". The "PersonCreated" event saves a Person entity in a field and the "GroupSelected" event takes the saved Person, creates a Group association and saves them to a database.
This view/view model doesn't do anything until the events get raised so I load the following sub views into my the region.
These views/view models fire the events which get handled by the master view.
I also have an edit view where I want to re-use the select group view.
I can do this by subscribing to the appropriate events in the EditPersonMaster view model.
My question really is, is this the appropriate way to do this? Because I'm using loosely coupled events I don't get any feedback into the sub-View/ViewModels if there's an error when creating/reassigning? I could probably fire another "ErrorBlah" event for the inner view/model to handle and update the view.
Is there another way to do this? Composite commands don't seem to fit the bill but maybe I don't understand them correctly.
Here is how I understood your question: You have persons stored in a database, which have a property/column group. In your UI, you want to create persons and assign the group property. Also, you want to be able to edit the group property of existing persons in a different region/page/master. You want to reuse the control for assigning the group. Your controls fire an event, which is handled by the Master in a way that it creates the entries in the database (is that correct?). Your question is whether this is a good approach and what alternatives you have?
I see two options:
1. Modularize your business logic:
You could inject a data service into your ViewModels, which could access the database directly. This way you can handle errors etc.. directly where they occur and don't have to pass them through the whole system. If you want to notify other modules of changes on the database (specifying the changed dataset or so), you can do so with a composite event. I think of the PRISM modules more as of complete elements, including UI and business logic and keep communication between them as little as possible.
2. Keep your business logic central and share it:
If you want to stick to your architecture, have singleton Model which is injected into the ViewModels. Manage your state in the model and have the ViewModels pick the pieces they want to provide to their view.
Hope I got he point, though...

Common model among multiple views

New to WPF. I have a Product model that is an L2S entity. I am creating an application in WPF to edit the product information to potentially replace an old Windows forms app I have. the application has a tab control with a number of tabs on it, such as Packaging, Marketing, Photos, Construction, etc.
My question is how do I structure this in a MVVM system. Do I have a separate view for each tab, each with it's own view model relating to it's particular subset of the Product model? Or do I have a single view with the tab control and all of the fields and a single view model to encompass the model in it's entirety? Or am I going about it completely wrong?
I feel like the first option is the way to go, but then I am also unsure of how to share the same model across multiple view models. Can anyone shed some light on this for me?
--Edit--
Examples of data on the pages:
Marketing has several text fields, and a few subset entity collections such as features, applications, and cross references.
Photos handles a collection of Photos for the product
Packaging and Construction are each a large collection of text fields/combos/checkboxes related to their respective information in the Product
With this minimum of info you've provided I would suggest following solution:
Main ProductView view
Separate View for the each tab
Main container ViewModel: ProductViewModel
For complex tabs separate view model as well. For instance you would have a separate PackagingViewModel so ProductViewModel should expose public PackagingViewModel Packaging property
ProductViewModel should accept all model-related stuff (perhaps some services, model entity, etc) and then initialize all other child view models.

Loading large graphs and detaching them

I am developing an application that uses Entity Framework and WPF with MVVM design pattern. I have a number of entities, but to keep it simple, lets work with just a subset of them. Companies which can contain Contacts, Addresses, and PhoneNumbers; the aforementioned Contacts which contain Addresses, PhoneNumbers and Shipments.
Originally I was loading these entities from the database and leaving the DataContext open to use again later. This presented problems from a concurrency aspect as any of the objects that got updated may very well not be represented correctly in other parts of the program since those parts had not been updated.
I am trying something new. In my MainViewModel (which can easily be accessed from every other ViewModel) I have several ObservableCollections (my generic collection of choice when working with WPF Databound objects) which I intent to temporarily store my entities. Also there are several methods which will take care of adding entities to the context, attaching, detaching, saving changes etc. In my Record Collection displaying ViewModels (for instance the CompaniesViewModel) I have a backgroundworker load the entities, detach them, and store them in the Collections in MainViewModel. Unfortunately, I apparently have to create explicit queries such as:
Dim results = From Comp As Company In RVShipContext.Companies _
.Include("Contacts.PhoneNumbers") _
.Include("Addresses") _
.Include("PhoneNumbers") Select Comp
Mind you, that is not so much of a problem, except when it comes time to load up a Contact and now I have to go back (attach, query, detach) to get the Addresses, and Shipments. Now, I don't have a real problem with that, but some of these graphs are going to be several layers deep. A Shimpent contains one or more Packages contains one or more DiskSets contains several disks.
Is there a way to load large graphs easily when using detached entities?
Is there a way to use LazyLoading effectively when using detached entities?
Is keeping my entities in a central set of collections (accessible to other parts of the program) a good idea or should I abandon it before I spend an inordinate amount of time setting up infrastructure for it?
Any help would be greatly appreciated!
You should abandon your current approach. I don't understand WPF an VMMV but in case of MVP (model-view-presenter) you should use one ObjectContext / DbContext instance per Presenter and keep your entities attached. Check this article - it is about NHibernate but principle is the same. Similar approach should be used with VMMV.
The complexity of your query looks like you are trying to load everything to shared context which is very problematic solution. Especially detaching entities in stateful application like WPF app looks like big overhead and a lot of work to do when attaching changes back to context instead of using attached entities and let the context track changes for you. Also keeping entities attached solves the problem with lazy loading.

The model in MVVM: business object or something else?

I'm trying to get to grips with MVVM and so I've read a bunch of articles - most focus on the View -> ViewModel relationship and there's general agreement about what's what. The ViewModel -> Model relationship and what constitutes the Model gets less focus and there's disagreement. I'm confused and would like some help. For example, this article describes the Model as a business object whereas this article describes a class which manages business objects. Are either of these right or is it something else?
I think you are on the right track. The "model" is vague in a lot of cases because it is different things to other people, and rightly so.
For me, my business objects that come back from my WCF service I consider my model. Because of this my projects don't have that pretty file structure with the holy trinity of namespaces: *.Models, *.ViewModels, and *.Views. I personally consider objects coming back from business logic or anything of that nature the "model".
Some people tend to lump both the business objects and the business logic together and call that the "Model", but I find that a little confusing because I picture a Model to be sort of more static than I do business logic, but it's semantics.
So when you look at examples of MVVM projects and don't see anything very clearly "Model", it's just because folks treat them differently. Unless an application is very standalone, I would actually be very suspicious of an application with an actual *.Model namespace, to be honest.
The other thing that is great here is that many times you already have an investment in these types of business objects and I think a lot of people see "MVVM" and immediately assume they need to start defining the "M", even though what they already have is perfectly fine.
The confusion between a Model and a ViewModel is pretty common, too. Essentially I know I need a ViewModel if I need a combination of data and behavior. For example, I wouldn't expect INotifyPropertyChanged to be implemented on a Model, but I would a ViewModel.
From the other answers it should be obvious that the relationship between ViewModel and Model is somewhat fuzzy. Be aware that there is nothing stopping you from having ViewModel and Model in the same class, and when your requirements in a particular area are simple enough maybe this is all that you need!
How you structure the separation between ViewModel and Model will very much depend on the needs of the project or software that requires it, how demanding your deadlines are and how much you care about having a well structured and maintainable code base.
Separating ViewModel and Model is simply a way of structuring your code. There are many different ways of structuring your code, even within this pattern! It should be no surprise then that you will hear different approaches preached by different programmers. The main thing is that the separation can help to simplify and make reusable the independent portions of code. When you have cleanly separated business data, business logic and presentation logic you can easily mix, match and reuse your views, logic and data to create new UIs. The separated and simplified code is also often easier to understand, test, debug and maintain.
Obviously not everyone will agree with this answer. I think that is part of the inherent fuzziness of the problem. In general you need to consider and trade-off the advantages versus the costs of having a separation between ViewModel and Model and know that it is not always a simple task to decide what goes in the ViewModel and what goes in the Model. It will probably help to lay down some ground rules that you or your organisation will follow and then evolve your rules as you understand which level of separation best suits your problem domain.
I think it is worth mentioning that I used to use a similar approach to MVVM when programming Windows Forms and the fact the WPF has more direct support for this (in the form of data binding and commands) has really made my day.
There are a lot of different implementations and interpretations.
In my mind, however, the value of the ViewModel comes from coordination.
The Model is representative of business data. It encapsulates scalar information, as opposed to process.
The View is obviously the presentation of the model.
The ViewModel is a coordinator. In my opinion, the job of the view model is to coordinate between the view and the model. It should NOT contain business logic, but in fact interface with business services.
For example, if you have a view that is a list of widgets, and the widgets are grabbed from a service, then I'd posit:
The Model is a List<Widget>
The View is a ListBox bound to the ViewModel property Widgets
The ViewModel exposes the Widgets property. It also has a IWidgetService reference it can call to in order to get those Widgets.
In this case, the view is coordinating with a business object so the view doesn't have to know anything about it. The model should be ignorant of view models, views, and every thing else ... they should exist independent of how they are used. The IWidgetService would get bound to the view model using some source of dependency injection container, either constructor injection with Unity or an import using MEF, etc.
Hope that makes sense ... don't overload your viewmodel. Think of it as a coordinator that understands business objects and the model, but has no knowledge of the view or how business process is performed.
The value added by the model is its decoupling from the ViewModel and the View. Think if you had to construct and maintain business logic in the ViewModel you would have lots of duplicate code.
For instance - if you had a car game with a GearBoxView (a control in the CockpitView), CarViewModel and CarModel - the advantage of abstracting what is in the CarModel from the CarViewModel is that the CarModel can be used in the WorldViewModel and any other ViewModel. The CarModel can have relationships with other Models (GearsModel, WheelModel, etc).
Your question specifically asked about using a Model as a business object or to manage business objects: my answer is it can do both - and should be responsible for both.
Heres an example
public class WorldModel //Is a business object (aka game object)
{
private List<CarModel> _cars;
public List<CarModel> Cars
{
get //Here's some management of other business objects
{
//hits NetworkIO in a multiplayer game
if(_cars == null)
{
_cars = myExternalDataSource.GetCarsInMyGame();
}
return _cars;
}
}
public Level CurrentRaceCourse { get; set; }
public CourseTime TimeElapsed { get; set; }
}
I think of the model as something that contains the smallest units of business entities. The entities in the model are used not only across the view models in my application but even across applications. So one model provides for many applications and, for those applications using MVVM, many view models.
The view model is an arbitrary collection of entities from the model that are brought together to serve whatever the view needs. If a view requires 2 of these and 1 of those, then its view model provisions them from the model. Generally, I have 1 view model per view.
So a model is like a grocery store. A view model is like a shopping cart. And a view is like a household.
Each household has unique requirements. And each household has its own shopping cart that cherry picks what the household needs from the grocery store.
My thoughts
(The "Model")
Have one model. Just data no methods (except if apt for the platform some -simple- getters/setters).
(The "View Model")
To my mind the rationale for a view model is:
(1) to provide a lower-RAM-requirement backup copy of fields so views hidden behind other views can be unloaded and reloaded (to conserve RAM until they reappear from behind views covering them). Obviously this is a general concept that may not be useful or worthwhile to your app.
(2) in apps with more complex data models, it is less work to lay out all application fields in a view model than to create one reduced model corresponding to the fields of each possible data change, and easier to maintain, and often not significantly slower performance wise.
If neither of these apply, use of a view model is inapt in my view.
If view models are apt, have a one to one relationship of view models to views.
It may be important to note/remind/point out that with a lot of UI toolkits if the exact same "String" object is referenced twice (both in the model and the view model) then the memory used by the String object itself is not double, it is only a little more (enough to store an extra reference to the String).
(The "View")
The only code in the view should be (the required) to show/hide/rearrange/populate controls for initial view load and (when user is scrolling or clicking show/hide detail buttons etc) showing/hiding parts of the view, and to pass any more significant events to the "rest" of the code. If any text formatting or drawing or similar is required, the view should call the "rest" of the code to do that dirty work.
(The "View Model" revisited)
If the (...facts of which views are showing and...) the values of view fields are to be persistent ie survive app shutdown/restart, the view model is part of the model :--: otherwise it is not.
(The "View" revisited)
The view ensures that the view model is as synch'ed with the view in terms of field changes as is appropriate, which may be very synched (on each character change in a text field) or for example only upon initial form population or when user clicks some "Go" button or requests app shutdown.
(The "Rest")
App start event: Populate the model from SQL/network/files/whatever. If view model persistent, construct views attached to view models, otherwise create initial view model(s) and create initial views attached to them.
On commit after user transaction or on app shutdown event: Send model to SQL/networkl/files/whatever.
Allow the user to ("effectively") edit the view model through the view (whether you should update the view model on the minutest change of a character in a text field or only when the user clicks some "Go" button depends on the particular app you are writing and what is easiest in the UI toolkit you are using).
On some application event: the event handlers look at the data in the view model (new data from the user), update the model as required, create/delete views and view models as required, flush the model / view models as required (to conserve RAM).
When new view must be shown: Populate each viewmodel from the model just after the viewmodel is created. Then create view attached to view model.
(Related issue: what if any data set primarily for display (not editing) should not be entirely loaded into RAM?)
For sets of objects that should not be entirely held in RAM cause of RAM use considerations, create an abstract interface to access information on the overall count of objects and also to access the objects one at a time.
The interface and its "interface consumer" may have to deal with the number of objects being unknown/estimated and/or changing depending on the API source providing the objects. This interface can be the same for the model and the view model.
(Related issue: what if any data set primarily for editing should not be entirely loaded into RAM?)
Use a custom paging system through a slightly different interface. Support modified bits for fields and deleted nits for objects - these kept in the object. Page unused data out to disk. Use encryption if necessary. When editing of set done, iterate it (loading in pages at a time - one page can be say 100 objects) and write all data or only changes in transaction or batch as appropriate.
(Conceptual significance of MVVM?)
Clean platform-agnostic way to allow and lose data changes in views without corrupting model; and to allow only validated data through to the model which remains as the "master" sanitised version of data.
Crucial to understanding the why is that flows from view model to model are conditional on data validation of user input whereas flows in the opposite direction from model to view model are not.
The separation is achieved by placing code that knows about all three (M/V/VM) into a core object responsible for handling application events including startup and shutdown at a high level. This code necessarily references individual fields as well as objects. If it didn't I don't think easy separation of the other objects can be achieved.
In response to your original question, it is a question of degree of interrelationships of validation rules on update of fields in the model.
Models are flat where they can be but with references to submodels, directly for one-to-one relationships or through arrays or other container objects for one-to-many relationships.
If the complexity of validation rules is such that merely validating a successful user form fill or incoming message against a list of field regular expressions and numeric ranges (and checking any objects against a cached or specially fetched copy of relevant reference objects and/or keys) is enough to guarantee that updates to business objects will be 'with integrity', and the rules are tested by the application as part of the event handler, then the model can just have simple getters and setters.
The application may perhaps (best) do this directly in-line in event handlers where the number of rules is so simple.
In some cases it may be better even to put these simple rules in the setters on the model but this validation overhead is then incurred on database load unless you have extra functions for setting without validate. So for simpler data models I tend to keep the validation in application event handlers to avoid writing these extra setters.
But if the rules are more complex either:
(a) a single method taking a special object that is really a composite of the usual business objects containing data for myriad field changes is written for each complex model change, and the method can succeed or fail depending on validation of the rules - facade pattern;
or
(b) a "dry run" / hypothesis / "trial" copy of the model or a subset of the model is created first, setting one property at a time, and then a validation routine run on the copy. If validation is successful, the changes are assimilated into the main model otherwise the data is discarded and an error raised.
The simple getter/setter approach is in my view preferred when analysing each individual transaction unless the vast majority of updates for your app are complex, in which case one can use the facade pattern throughout.
The other way the model ends up getting more complex than a bunch of fields with (possibly) simple getters/setters is if you start "enhancing" classes' getters/setters (with an O2R mapper tool), or adding extra aspects like calls to transaction monitoring APIs, security APIs (to check permissions, for logging etc), accounting APIs, methods that pre-fetch any related data needed for a get or set, or whatever upon get or set. See "aspect-oriented programming" for an exposition on this area.

Resources