Hello fellow developers.
First of all I apologize beforehand for the wall of text that follows, but after a day going crazy on this, I need to call for help.
I've stumbled across a problem I cannot seem to solve. I'll try to describe the scenario in the best possible way.
Task at hand: in an existing Asp.Net Mvc application, create a lookup table for an integer field, and use the textual value from the lookup in the editing view. When saving, we must first check if the lookup already has a corresponding text value for the same Root ID. If there is, use that. Otherwise, create it and then use it.
The structure:
The data model is a graph of objects where we have the root object, a collection of level A child objects, and every level A child object has a collection of level B child objects, so something like this:
Root (with fields)
Level A child (with fields) x n
Level B child (with fields) x n
The field we have to handle is on the LevelB objects.
There is a single Mvc view that handles the whole data. For collection objects, all fields are named like levelA1levelB1MyField, levelA1levelB2MyField, etc so every single field has unique name during the post. When the post happens, all values are read through a formCollection parameter which has average 120/130 keys. The keys are isolated by splitting them and looping on the numerical part of the names, values are read and parsed to the expected types and assigned to the object graph.
The datalayer part backing the object graph is all stored procedures, and all the mapping (both object to sproc and sproc to object) is hand written. There's a single stored procedure for the read part, which gets multiple datasets, and the method calling it reads the datasets and creates the object graph.
For the saving, there are multiple sprocs, mainly a "CreateRoot" and "UpdateRoot". When the code has to perform such tasks, the following happens:
For create scenario, "CreateRoot" is called, then the sprocs "CreateLevelA" and "CreateLevelB" are called in loop for each element in the graph;
For update scenario, "UpdateRoot" is called, which internally deletes all "LevelA" and "LevelB" items, then the code recreates them calling the aforementioned sprocs in loop.
Last useful piece of information is that the "business objects graph" is used directly as a viewmodel in the view, instead of being mapped to a plain "html friendly" viewmodel. This is maybe what is causing me the most trouble.
So now the textbox on the view handles an "integer" field. That field must now accept a string. The field on LevelB must remain an integer, only with a lookup table (with FK of course) and the text field from the lookup must be used.
The approaches I tried with no success:
My first thought was to change the datatype on the property MyField from integer to string on the object, then change the sprocs accordingly and handle the join at sproc level: I'd have a consistent object for my view, and the read/write sprocs could translate from string to integer and viceversa, but I can't do that because the join keys to retrieve the integer when writing are part of the Root item (as I stated in the first lines of this wall of text), which I don't know in the CreateLevelB sproc, and changing the whole chain of calls to pass those parameters would have a huge impact on the rest of the application, so no good.
My next try was to keep things "as they are" and call some "translation methods": when reading, pass the integer to the view, and there call the translation method to display the text value. When saving, use the posted text to retrieve the integer. The save part would work, I'd have all the parameters I need, but for the read part, I'd have to instantiate the "data access layer" and call its method at View level, and there's no need to explain why that is a very bad choice, so I ruled this out too.
Now I'm out of options (or ideas anyway). Any suggestion to solve this is very welcome, and also if something is not clear enough just point it out and I will edit my post with more accurate information.
Thanks.
This is not a real answer but you could rip out all sprocs and use the updating facilities of an OR mapper. This will resolve all the layering issues. You just update data how you see fit and submit at the end.
I guess this would also make the questions around "should I use an int or a string" go away.
Edit: After reading your comment I thought of the following: Do not implement alternative 1. You rather want to sacrifice code quality in the view than in the data storage model. The last one is more important and more centrally used.
I would not be too concerned with messing up the view by calling the DAL from it or the like. Changes in a view are localized and do not mess up the application's architecture. They just degrade the view.
Maybe you could create a view model in your controller and do the translations between DAL-model and view model? Or is that pattern not allowed?
Related
I have a (not quite valid) CSV file that contains rows of multiple types. Any record could be one of about 6 different types and each type has a different number of properties. The first part of any row contains the timestamp and the type of record, followed by a standard CSV of the data.
Example
1456057920 PERSON, Ted Danson, 123 Fake Street, 555-123-3214, blah
1476195120 PLACE, Detroit, Michigan, 12345
1440581532 THING, Bucket, Has holes, Not a good bucket
And to make matters more complex, I need to be able to do different things with the records depending on certain criteria. So a PERSON type can be automatically inserted into a DB without user input, but a THING type would be displayed on screen for the user to review and approve before adding to DB and continuing the parse, etc.
Normally, I would use a library like CsvHelper to map the records to a type, but in this case since the types could be different, and the first part uses a space instead of comma, I dont know how to do that with a standard CSV library. So currently how I am doing it each loop is:
String split based off comma.
Split the first array item by the space.
Use a switch statement to determine the type and create the object.
Put that object into a List of type object.
Get confused as to where to go now because i now have a list of various types and will have to use yet another switch or if to determine the next parts.
I don't really know for sure if I will actually need that List but I have a feeling the user will want the ability to manually flip through records in the file.
By this point, this is starting to make for very long, confusing code, and my gut feeling tells me there has to be a cleaner way to do this. I thought maybe using Type.GetType(string) would help simplify the code some, but this seems like it might be terribly inefficient in a loop with 10k+ records and might make things even more confusing. I then thought maybe making some interfaces might help, but I'm not the greatest at using interfaces in this context and I seem to end up in about this same situation.
So what would be a more manageable way to parse this file? Are there any C# parsing libraries out there that would be able to handle something like this?
You can implement an IRecord interface that has a Timestamp property and a Process method (perhaps others as well).
Then, implement concrete types for each type of record.
Use a switch statement to determine the type and create and populate the correct concrete type.
Place each object in a List
After that you can do whatever you need. Some examples:
Loop through each item and call Process() to handle it.
Use linq .OfType<{concrete type}> to segment the list. (Warning with 10k
records, this would be slow since it would traverse the entire list for each concrete type.)
Use an overridden ToString method to give a single text representation of the IRecord
If using WPF, you can define a datatype template for each concrete type, bind an ItemsControl derivative to a collection of IRecords and your "detail" display (e.g. ListItem or separate ContentControl) will automagically display the item using the correct DataTemplate
Continuing in my comment - well that depends. What u described is actually pretty good for starters, u can of course expand it to a series of factories one for each object type - so that you move from explicit switch into searching for first factory that can parse a line. Might prove useful if u are looking to adding more object types in the future - you just add then another factory for new kind of object. Up to you if these objects should share a common interface. Interface is used generally to define a a behavior, so it doesn't seem so. Maybe you should rather just a Dictionary? You need to ask urself if you actually need strongly typed objects here? Maybe what you need is a simple class with ObjectType property and Dictionary of properties with some helper methods for easy typed properties access like GetBool, GetInt or generic Get?
I have a quite big dilemma nowadays about general viewmodel design concepts. I mean general, like it's not exactly bound to a given language or environment: I had same dilemma when I wrote viewmodels for Winforms, WPF or KnockoutJS.
As a simplified use case, consider that I have a view where I have to select a country and a city from two select boxes. Both are represented in the database with a unique ID, a Name, and some other relevant information like - let's say - Population. Now imagine that I have to present a textual form of the currently selected data in for example the view's heading like "You've selected London, England". Now here is my two alternatives for creating a viewmodel, I will try to enumerate the pros/contras which I'm already thinking of below each version. The code is written in kind of pseudo way to be as generic as possible.
class RegionModel {
ID: number;
Name: string;
Population: number;
}
Version 1: Storing the selected object.
class MainView {
SelectedCountry: RegionModel;
SelectedCity: RegionModel;
SelectionInfo: string; // computed, should return the "You've selected ...." caption
Countries: List<RegionModel>; // datasource for country select
Cities: List<RegionModel> // datasource for city select
}
Pros:
Straightforward and easy to understand due to that the selected
item's type is the same as the selectable items' type.
Easy to compute such infos like "You've selected ..." because all the
members of the currently selected item are present directly.
Cons:
It holds more information than usually a consumer API needs. Usually
it needs only the ID.
If it's used in a client-side app, the whole selected object will be
returned to the server, consuming bandwidth.
If the consumer API needs only ID's (like in most cases), I have to
solve some kind of conversion before I pass it. In a web app probably
during serialization to JSON for example.
Version 2: Storing only the ID's of the selected items
class MainView {
SelectedCountryID: number;
SelectedCityID: number;
SelectionInfo: string; // computed, should return the "You've selected ...." caption
Countries: List<RegionModel>; // datasource for country select
Cities: List<RegionModel> // datasource for city select
}
Pros:
It's efficient in the way that it contains only the information which
is most likely needed by consumer APIs.
No additional conversion is needed, and efficiently can be passed
nearly "as is" to a server-side or other API.
Cons:
Not so straightforward and readable (in my opinion).
What about computing the info string? That's now much harder, I need
to grab the needed members from the selection source lists with a
search by the given ID, so it depends heavily on the consistency of
those lists (I mean the item must be present there).
I hope it won't be closed quickly as unconstructive. Any kind of advices, thoughts or experiences will be appreciated. Also, if the answer is "it depends", please try to give my some points where and when to use which.
UPDATE
I think my question was a bit unclear. I know about decoupling viewmodel from database entities, here I never mentioned database entities. I mentioned an "abstract consumer API". In a concrete scenario: if the API needs the selected items' Names, and my API needs only the IDs, which alternative should I choose, and where should do the conversion?
For example my server expects a data format like this (JSON):
{
"SelectedCountryID": 2,
"SelectedCityID": 5
}
and nothing else. How could I handle it in an elegant way? I would like to avoid repeating myself by doing a manual conversion.
Depending on how your datasources are implemented, it may make not difference: if you are retrieving the list of countries and cities, you can either store a reference to the selected value, to one of its fields or its index in the list.
Disregarding that, you should decouple your view model entities from your database entities and put into your view model ones only those fields required by the views. This way, your information traffic is minimized and your code is less affected by changes in the database.
EDIT following OP's update:
Talking about interacting with an API instead of a database, I think you can apply the same ideas, just replacing "database entities" by "service layer entities" (for instance, the JSON coming in/out your server). Take the returned data that into your view model objects, holding those attributes that you need. Obviously you also may need to store an id as you stated, when you'll need to refer to the same entity later on.
From a theoretical point of view, you should not include any other fields not consumed by the view, but you could do so depending on your requirements. For instance, in cases when you'll need to pass those fields back to the service layer and you don't want to query again by id to retrieve the service entity. However there are other alternatives to this (for example, some kind of cache), the exact balance depends on your requirements.
Base on MVVM pattern your viewModel should be an object with all properties which you need to display in view. ViewModel should be only used to be strictly binded to the view. Anyway your example it's not very good in my opinion. You shouldn't think about viewModel in case of storing something, please think more about presenting data.
Please remember that before you have data in database you have to insert it. So if you have some form with First Name and Last Name, user at first must fill this form and data must be insert into database, without it you don't have any ID.
To summarize in my opinion viewModel should have properties which you have to present to the end-user.
I have a case where in the columns of Datagrid are not fixed . i.e it has to be generated depending on some conditions.
How can i store the values in the DB and display the datagrid with them using MVVM pattern.
P.S : I have a main grid and a sub grid and depending on the value he chooses in the main grid i need to form the below grid. My concern also in storing it in the DB, since there can be 5 columns or sometimes 20.
Any similar links or references will also be useful.
This can be totally done in an MVVM compliant way, but isn't necessarily trivial for a beginner, and isn't appropriate for simple applications.
One approach I like to use is to keep a collection of column descriptors serialised in the database1. The column descriptors are simply my own custom DTO data classes and contain properties related to a column, i.e. width, column type, whether it is visible, whether it's visibility can be toggled, it's ordinal, etc. This is all done using simple structs and or primitive .Net types, but specifically doesn't have any UI related data types in it at all2.
This list of ColumnDescriptors can then be serialiased to and from XML, and stored in the database either in an nvarchar or XML column. Especially on SQL Server an XML column is better as you can natively query deep into the XML structures stored in the database column.
As it is a UI layout thing, it is up to the view to query the right set of column descriptors from the database, I then pump that collection through a static GridColumnFactory class which iterates the descriptor objects and creates me the appropriate grid columns and assigns the appropriate values to them. Once the factory returns that collection the view can then add them to the DataGrid's columns collection.
The benefits of this approach:
If I swap out the DataGrid that is used (i.e. swap from one vendor to another, say DevExpress to ComponentOne or native WPF), I can simply change the types of columns returned from the factory class
If I swap anything in the UI then I don't need to touch the column descriptors that are stored.
Serialising to and from XML means that if I do add/remove properties from the descriptors then older stored copies can still be accommodated, they aren't instantly broken the moment I release an update
One of the best features of all is that I can change the stored column layouts with a simple SQL statement, I don't have to also release compiled code
One last thing - using column descriptors makes it trivial to implement a user specified layout, i.e. when you let them drag columns around and then want to save the layout for next time
If I want to get really funky, the column descriptors can be returned from a webservice
1 For a website these could also be stored in a loose XML file which is then read in and kept in cache.
2 For this approach you should always avoid using specialised or vendor specific data types, as they don't necessarily serialise well (if at all), and will become a weak point in the future - these will be the most likely things you have to change, and if these change you break any stored descriptors you've already got.
this is the more or less the schema i want to generate my dynamic form on based on the fields above. i am going to add the direction , max size, default value and like wise some more fields in it. i am looking for recommended ways and methods in asp.net mvc for generating dynamic fields at runtime.
1) if i design my own engine for it then how? i am interested on that also but this is the last thing i am looking at. method to apply validation is very important in my scenario
2) any framework that may lessen the working time? or anything else?
I'll describe the generic approach, I don't want to code it for you.
Create meta class to describe each field (type, name, maxlength, null value handling, data source for combos, etc.)
Load the data from database and preprocess it
Populate the ViewBag with sanitized values
Create helper that will generated the control specific code
Html.ControlFor("Name", metadata);
Loop in view over the metadata collection.
which will generate textbox, combobox, etc.
Remeber that MVC form handling works over list of key-values, it's the Binder feature that converts it to objects. Saving data won't be difficult (dynamically created INSERT, UPDATE statement, ...).
I am looking for the name of this pattern and to understand the reasons for this design.
I have:
Input data(from DB): being put in an
object, containing data
corresponding to a table row and
also the objects of it's foreign
keys. Data could come from DB or
generated from code for unit
testing.
A calculator: that analyses,
processes and modify this data. I
want the input data to stay external
to this calculator to be able to
unit test it with data generated
from code or coming from and XML
file instead of a DB.
Results data: Then I need to update
my database, BUT also those results
can be used to validate against
expected results in the case of unit
testing.
Is this a Separation of Concern Pattern? Is there other known patterns involved here?
Should my result object, containing result data, sit in the same object as my input data and null at the begining then updated after the processing, or should the results object be totally independent from the input object, and why please.
I would suggest that your output object be completely independent from your input object. Otherwise your input object has to "know" about the output object. That seems unreasonable because any time you change the output object, you by extension change the input object. Or perhaps you want multiple different output objects. Then the input object needs to know about all of the output objects, or you have an untyped reference (i.e. object in .NET) that you'll need to cast.
The input object is exactly that: it represents the data as its received from your data store or whatever. That input data is passed through some transformation to create an output object of some kind, which might bear very little relation to the input object.
In short, there's no good reason for the input object to have any knowledge of the output object. In fact, the input object shouldn't even be concerned that the output object exists. Giving the input object that knowledge will result in unnecessary coupling, which will make it more difficult to modify your code in the future.
There are many different things in your list which seem to specialized to be part of one single pattern. The cornerstone of you describe seems to be the Repository pattern though.
At a high level, I would refer to this as "ETL", "Extract, Transform and Load". This term is more commonly used in a BI context, but it is the exact same thing conceptually.