i have to create a dialog where columns has to be generated at run time, earlier i was using WPF data grid so generating columns at runtime was not a problem. Now i have to use View Model i need to have properties for whatever fields i want to display in view as columns. the number of columns are not known at design time, its not possible for set binding for the data grid.It will be crazy if i create properties at runtime using reflection, is there any way that i can bind runtime generated fields to a data grid column.
If you're on .NET 4 you can use ExpandoObject. It implements INotifyPropertyChanged for you.
Related
We would like to create an OData REST API. Our data model is such that each customer has their own database. All database objects have the same definition across all customer databases, with the exception of a single table.
The customer specific table we will call Contact. When a customer adds a column the system creates a column with a standardised name with a definition translated from options selected by the user in the UI. The user only refers to the column data by a field name they have specified to enable the user to be able to generate friendly queries.
It seems to me that the following approaches could be used to enable OData for the model described:
1) Create an OData open type to cater for the dynamic properties. This has the disadvantage of user requests for a customer not providing an indication of the dynamic properties that can be queried against. Even though they will be known for the user (via token authentication). Also, because dynamic properties are a dictionary, some data pivoting and inefficient query writing would be required. Not sure how to implement the IQueryable handling of query options for the dynamic properties to enable our own custom field querying.
2) Create a POCO class with e.g. 50 properties; CustomField1, CustomField2... Then somehow control which fields are exposed for use in OData calls. We would then include a separate API call to expose the custom field mapping. E.g. custom field friendly name of MobileNumber = CustomField12.
3) At runtime, check to see if column definitions of table changed since last check. If have, generate class specific to customer using CodeDom and register it with OData. Aiming for a unique URL for each customer. E.g. http://domain.name/{customer guid}/odata
I think the ideal for us is option 2. However, the fact the CustomField1 could be an underlying SQL data type of nvarchar, int, decimal, datetime, etc, there are added complications.
Has anyone a working example of how to achieve what has been described, satisfactorily?
Thanks in advance for any help.
Rik
We have run into a similar situation but with our entire dataset being unknown until runtime. Using the ODataConventionModelBuilder and EdmModel classes, you can add properties dynamically to the model at runtime.
I'm not sure whether you will have to manually add all of the properties for this object type even though only some of them are unknown or whether you can add your main object and then add your dynamic ones afterwards, but I guess either would be workable.
If you can get hold of which type of user it is on the server, you could then add only the properties that you are interested in (like option 3 but not having to CodeDom).
There is an example of this kind of untyped OData server in the OData samples here that should get you started: https://github.com/OData/ODataSamples/tree/master/WebApi/v4/ODataUntypedSample
The research we carried out actually posed Option 1 as the most suitable approach for some operations. i.e. Create an SQL view that unpivots the data in a table to a key/value pair of column name/column value for each column in the table. This was suitable for queries returning small datasets. This was far less effort than Option 3 and less confusing for the user than Option 2. The unpivot query converted the field values to nvarchar (string) values and thus meant that filtering in the UI by column value data types was not simple to achieve. (If we decide to implement this ability, I believe this can be achieved by creating a custom attribute that derives from EnablQueryAttribute, marking the controller action with it and manipulate the IQueryable before execution).
However, we wanted to expose a /Contacts/Export endpoint that when called would output the columns from a table with a fixed schema joined on a table with a client specific schema and output to a CSV file. All the while utilising the OData supported filter syntax. One of our customer databases has more than 12 million rows of data and is made up of approximately 30 columns.
To achieve this it looks like our best bet would have been to work with the Microsoft.OData.Core.UriParser.UriQueryExpressionParser class, unfortunately Microsoft in their wisdom have declared this as internal, as well as many of it's dependants.
Walking an abstract syntax tree built from OData supported query options and applying our own visitor to each node to build some dynamic Linq query/SQL seems like a possible solution.
For the time-being we will simply implement a cut-down set of supported $filter criteria without the support for grouping parenthesis.
For a openui5 component I need to bind multiple models and is investigating what the best way to do this is.
The models are both JSONModel and XMLModel.
The background is that I want provide the user choice of multiple source to use for the custom openui5-spitz-reader component https://github.com/elsewhat/openui5-spritz-reader
Each of the selection the user can make (BBC World News, Reddit /r/worldnews), has a single Model populated.
During runtime, I need to combine all the Models the user has selected and bind the combined content towards the items aggregation of the openui5-spitz-reader component.
You can use named models on aggregations see Multimodel Support - example using multiple models on an element JSBin OData Model dynamic column and data binding
I am not sure if you can bind data from 2 models on a single aggregation, you may be able to achieve it using a factory function with the aggregation or a handler on the model binding - using a generic binding to sum aggregation
I am using inheritance currently in EF and feel like it is causing more issues than it is helping, especially with binding an aggregation of tables to a datagrid. I have given a screen of part of the model. What I am trying to do is bind FREQUENCY to a datagrid, and have the grid fields be based on the type of FREQ_POOL(which is a base class). So for instance, if I want a POOL_IA datagrid, then it would have those fields, as well as the few fields in FREQUENCY. I was using inheritance because it made since from an OO perspective. The alternative is to just have lots of 0..1 relationships that show the ability for FREQ_POOL to have an extension, but then I have no constraint in place saying that FREQ_POOL can only be ONE type. What is a better design to accomplish this and make data binding easier? Thank you for any guidance.
One approach may be creating a data grid that gets the data from FREQ_POOL and then put all the variables of POOL_IA (or the all the properties of derived class using reflection) and FREQUENCY .
If you really don't need using objects while binding your data grid and able to use DataSet the another approach may be getting all the properties and the values of entry with Context.Entry method on the fly and put it into DataSet dynamically.
I have a quick (hopefully) question on how to implement a composite field using MVVM.
I have 2 examples, one is on the sql end I am storing gps coordinates in the following manner "Latitude,Longitude" for instance "45.55555,-80.00000". the other example is storing feet and inches as a single double field with it being ft.in.
How should I go about this? Should I have two fields and in the model or Viewmodel composite them if the other piece exists? Should I bind them to the same field and somehow validate the sets?
thanks!
In the Model I normally use a structure/layout that is closest/easiest to the source so it can be easily/quickly read and written.
In the ViewModel I aim for a representation of the View to accommodate the bindings.
In general I make the ViewModel responsible for the transformation between the Model and ViewModel.
So whether or not a property of the ViewModel and the Model should have one field or two depends on the requirements of the View and the Source.
I am using EF 4.0, linq to entities, VS 2010 and SQL Server 2005 Stored Procedures to do a small search application. I have designed the EDM and the required layers. The presentation layer displays the search results properly.
The dilemma now is that the search should be flexible enough to read from different tables. For example, for the present search the application is reading from table A. Tomorrow the application may need to read from table B which may have totally different column names than table A.
Using EDM how can i map table A columns to Table B columns , without having any effect on the presentation layer.
Any suggestions/pointers/links would be greatly appreciated.
Thank you so much for your time and help.
I have used the Data Repository explained in the below link it shows the IDataRepositoryand the DataRepository class. also how you can fetch data dynamically using the fetch() and Find() functions
http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/
and its working pretty fine
I would recommend decoupling your presentation layer from your data. Create a business layer with a generic class that can be populated from different tables (entities) depending on your needs.
So, depending on the day, the generic class (or classes) would be populated from Table A, or Table B, or table X. However your presentation layer would be oblivious to this and only aware the data from the generic class.
You could design this a number of ways. One way would be to design an interface that the entities must conform to in order to populate the generic class. So no matter what the table structure is, you would need to map the data in it to the interface in order to populate the generic class and hence display it as search results.