First of all I'm using manual queries.
I'm having some issues organizing my service and repository layer. The problem is that I have some objects that are rather large aggregate objects that need to have basic data from their constituent objects in display mode but when being processed it needs to have all its child objects fully developed to avoid null errors and some other business logic errors.
So for example a Job has Customer, Supplier, Site, Machine, User, Run, Store, Component, Document, CheckSheet, Requisitions, OrderItems.
When displaying a Job we want to have things like customer name, supplier name, user, component description, store name, machine number, site name, number of checksheets. As you can see it's mostly just descriptions. However when I want to process a Job I need all of those objects fully developed.
Currently the way I'm doing it, which I don't like, is that when fetching a Job from the JobRepository it fully develops the Job object directly and fills the rest of the child objects with display values only and when I want to process a job I go ahead and call the respective repositories for each object to get a full object. There are some problems with this approach.
If we add a field to an object I have to potential look for changes in more than 1 places, which kind of defeats the purpose of a repository.
I can only have 2 'modes' of retrieval which is fully developed or display only. What if I want some of the child objects to be more developed but not others? For example when displaying OrderItems I'd like to have the Part object within it fully developed with prices and all.
I feel like things will get out of control soon with duplication everywhere and I need a better long term solution. Any help would be appreciated.
Related
I have an application with several Web API controllers and I now I have a requirement which is to be able to filter GET results by the object properties. I've been looking at using OData but I'm not sure if it's a good fit for a couple reasons:
The Web API controller does not have direct access to the DataContext, instead it gets data from our database through our "domain" layer so it has no visibility into our Entity Framework models.
Tying into the first item, the Web API deals with lightweight DTO model objects which are produced in the domain layer. This is effectively what hides the EF models. The issue here is I want these queries to be executed in our database but by the time the Web API method gets a collection from the domain layer all of the objects in the collection have been mapped to these DTO objects, so I don't see how the OData filter could possibly do it's job when the objects are once-removed from EF in this way.
This item may be the most important one: We don't really want to allow arbitrary querying against our Web API/Database. We just sort of want to leverage this OData library to avoid writing our own filters, and filter parsers/builders for every type of object that could be returned by one of our Web API endpoints.
Am I on the wrong track based on #3? If not, would we be able to use this OData library without significant refactoring to how our Web API and our EF interact?
I haven't had experience with OData, but from what I can see it's designed to be fed a Context and manages the interaction and returning of those models. I am definitely not a fan of returning Entities in any form to a client.
It's an ugly situation to be in, but when faced with this, my first course of action is to push back to the clients to justify their searching needs. The default request is almost always "Well, it would be nice to be able to search against everything." My answer to that is that I don't want to know what you want, I want to know what you need because I don't want to give you a loaded gun to shoot your own foot off with and then have you blame me because the system came grinding to a halt. Searching is a huge performance killer if it's too open-ended. It's hard to test for accuracy/relevance, and efficiently index for 100% of possible search cases when users only need 25% of those scenarios. If the client cannot tell you what searching they will need, and just want everything because they might need it, then they don't need it yet.
Personally I stick to specific search DTOs and translate those into the linq expressions.
If I was faced with a hard requirement to implement something like that, I would:
Try to push for these searches/reports to be done off a reporting replica that is synchronized with the live database. (To minimize the bleeding when some idiot managers fire up some wacky non-indexed search criteria so that it doesn't tie up the production DB where people are trying to do work.)
Create a new bounded DbContext specific for searching with separate entity definitions that only expose the minimum # of properties to represent search criteria and IDs.
Hook this bounded context into the API and OData. It will return "search results". When a user selects a search result, use the ID(s) against the API to load the applicable domain, or initiate an action, etc.
no. 1. is optional, a nice to have provided they can live with searches not "seeing" updated criteria until replicated. (I.e. a few seconds to minutes depending on replication strategy/size) Normally these searches are used for reporting-type queries so I'd push to keep these separate from the normal day-to-day searching options that users use. (I.e. an advanced search option or the like.)
Most of the examples I've seen online shows object change tracking in a WinForms/WPF context. Or if it's on the web, connected objects are used, therefore, the changes made to each object can be tracked.
In my scenario, the objects are disconnected once they leave the data layer (Mapped into business objects in WCF, and mapped into DTO on the MVC application)
When the users make changes to the object on MVC (e.g., changing 1 field property), how do I send that change from the View, all the way down to the DB?
I would like to have an audit table, that saves the changes made to a particular object. What I would like to save is the before & after values of an object only for the properties that we modified
I can think of a few ways to do this
1) Implement an IsDirty flag for each property for all Models in the MVC layer(or in the javascript?). Propagate that information all the way back down to the service layer, and finally the data layer.
2) Having this change tracking mechanism within the service layer would be great, but how would I then keep track of the "original" values after the modified values have been passed back from MVC?
3) Database triggers? But I'm not sure how to get started. Is this even possible?
Are there any known object change tracking implementations out there for an n-tier mvc-wcf solution?
Example of the audit table:
Audit table
Id Object Property OldValue NewValue
--------------------------------------------------------------------------------------
1 Customer Name Bob Joe
2 Customer Age 21 22
Possible solutions to this problem will depend in large part on what changes you allow in the database while the user is editing the data.
In otherwords, once it "leaves" the database, is it locked exclusively for the user or can other users or processes update it in the meantime?
For example, if the user can get the data and sit on it for a couple of hours or days, but the database continues to allow updates to the data, then you really want to track the changes the user has made to the version currently in the database, not the changes that the user made to the data they are viewing.
The way that we handle this scenario is to start a transaction, read the entire existing object, and then use reflection to compare the old and new values, logging the changes into an audit log. This gets a little complex when dealing with nested records, but is well worth the time spent to implement.
If, on the other hand, no other users or processes are allowed to alter the data, then you have a couple of different options that vary in complexity, data storage, and impact to existing data structures.
For example, you could modify each property in each of your classes to record when it has changed and keep a running tally of these changes in the class (obviously a base class implementation helps substantially here).
However, depending on the point at which you capture the user's changes (every time they update the field in the form, for example), this could generate a substantial amount of non-useful log information because you probably only want to know what changed from the database perspective, not from the UI perspective.
You could also deep clone the object and pass that around the layers. Then, when it is time to determine what has changed, you can again use reflection. However, depending on the size of your business objects, this approach can impose a hefty performance penalty since a complete copy has to be moved over the wire and retained with the original record.
You could also implement the same approach as the "updates allowed while editing" approach. This, in my mind, is the cleanest solution because the original data doesn't have to travel with the edited data, there is no possibility of tampering with the original data and it supports numerous clients without having to support the change tracking in the UI level.
There are two parts to your question:
How to do it in MVC:
The usual way: you send the changes back to the server, a controller handles them, etc. etc..
The is nothing unusual in your use case that mandates a change in the way MVC usually works.
It is better for your use case scenario for the changes to be encoded as individual change operations, not as a modified object were you need to use reflection to find out what changes if any the user made.
How to do it on the database:
This is probably your intended question:
First of all stay away from ORM frameworks, life is too complex as it.
On the last step of the save operation you should have the following information:
The objects and fields that need to change and their new values.
You need to keep track of the following information:
What the last change to the object you intend to modify in the database.
This can be obtained from the Audit table and needs to be saved in a Session (or Session like object).
Then you need to do the following in a transaction:
Obtain the last change to the object(s) being modified from the database.
If the objects have changed abort, and inform the user of the collision.
If not obtain the current values of the fields being changed.
Save the new values.
Update the Audit table.
I would use a stored procedure for this to make the process less chatty, and for greater separations of concerns between the database code and the application code.
I have 5 types of objects: place info (14 properties),owner company info (5 properties), picture, ratings (stores multiple vote results), comments.
All those 5 objects will gather to make one object (Place) which will have all the properties and information about all the Place's info, pictures, comments, etc
What I'm trying to achieve is to have a page that displays the place object and all it's properties. another issue, if I want to display the Owner Companies' profiles I'll have object for each owner company (but I'll add a sixth property which is a list of all the places they own)
I've been practicing for a while, but I never got into implementing and performance experience, but I sensed that it was too much!
What do you think ?
You have to examine the use case scenarios for your solution. Do you need to always show all of the data, or are you starting off with displaying only a portion of it? Are users likely to expand any collapsed items as part of regular usage or is this information only used in less common usages?
Depending on your answers it may be best to fetch and populate the entire page with all of the data at once, or it may be the case that only some data is needed to render the initial screen and the rest can be fetched on-demand.
In most cases the best solution is likely to involve fetching only the required data and to update the page dynamically using ajax queries as needed.
As for optimizing data access, you need to strike a balance between the number of database requests and the complexity of each individual request. Because of network latency it is often important to fetch as much as possible using as few queries as possible, even if this means you'll sometimes be fetching data that you do not always need. But if you include too much data in a single query, then computing all the joins may also be costly. It is quite rare to see a solution in which it is better to first fetch all root objects and then for every element go fetch some additional objects associated with that element. As such, design your solution to fetch all data at once, but include only what you really need and try to keep the number of involved tables to a minimum.
You have 3 issues to deal with really, and they are often split into DAL, BLL and UI
Your objects obviously belong in the BLL and if you're considering performance then you need to consider how your objects will be created and how they interface to the DAL. I have many objects with 50-200 properties so 14 properties is really no issue.
The UI side of it is seperate, and if you're considering the performance of displaying a lot of information onto a single page you'll consider tabbed content, grids etc.
Tackle it one thing at a time and see where your problems lie.
The past few days I have done a lot of research using the DAL/BLL/UI approach without a very clear understanding of how it will apply to my project. In the past, I have left out the BLL connecting my UI directly to the Data Access Layer (LINQtoSQL dbml). But, I do not think this is a good idea where I work now(or maybe even in the past) because we have a lot of different applications and I'd like to use the same DAL/BLL as they are built.
My question is, how does the BLL help me when, in most of my applications, all I really do is use the LinqtoSqlDataSource/GridView to connect to my datacontext to take care of all the updating/edit, etc. Also, each new web application will, at some level, require unique changes to the DAL/BLL to get the require data, possibly affecting other apps using the same DAL/BLL. Is this reuse of the DAL/BLL the right way of doing this or am I missing something?
I think the BLL comes in when I need to build, for example, a security classes for the various web applications that will be built. But, when I use the Linqtosqldatasource, why would I bother to connect it to the BLL?
DAL
LinqToSQL dbml DataContext.
Does using LinqToSQL change how I should use this design?
BLL
Security for various website used by company.
Query DAL return what(?) when using LinqToSQLDatSource., functions that handle various results sets(I am really unsure how this should work with BLL, sorry if the question is unclear)
UI
Reference only the BLL?
The DAL and BLL are separated by one often subtle, but key difference; business logic. Sounds moronically simple, but let me explain further because the distinctions can be VERY fine and yet impact architecture in huge ways.
Using Linq2SQL, the framework generates very simple objects that will each represent one record in one table. These objects are DTOs; they are lightwight, POCO (Plain Ol' CLR Object) classes that have only fields. The Linq2SQL framework knows how to instantiate and hydrate these objects from DB data, and similarly it can digest the data contained in one into SQLDML that creates or updates the DB record. However, few or none of the rules governing the relationship between fields of various objects are known at this level.
Your actual domain model should be smarter than this; at least smart enough to know that a property on an Order object named SubTotal should be equal to the sum of all ExtendedCosts of all OrderLines, and similarly, ExtendedCost should be the product of the UnitPrice and the Quantity. In many modern programs, your domain forms part of your BLL, at least to this extent. The objects created by Linq2SQL probably shouldn't have to know all this, especially if you aren't persisting SubTotal or ExtendedCost. If you rely on the Linq2SQL DTOs, you've basically tied yourself to what's called an Anemic Domain Model, which is a known anti-pattern. If the domain object can't keep itself internally consistent at least, then any object that works with the domain object must be trusted to keep it that way, requiring all those objects to know rules they shouldn't have to.
The UI should know about the domain, or if you prefer it should know some abstracted way to get the data from the domain for read-write purposes (generally encapsulated in objects called Controllers, which work with the domain layer and/or Linq2SQL). The UI should NOT have to know about the DB in any program of moderate size or larger; either the domain objects can hydrate themselves with a reference to objects in the DAL, or they are produced by custom objects in the DAL that you create to do the hydration, which are then given to the controller. The connected ADO model and interop with GridViews is admirable, but it doesn't allow for abstraction. Say you wanted to insert a web service layer in between the domain and UI, to allow the UI to be located on a mobile app that worked with data in your warehouse. You'd have to rebuild your UI, because you can no longer get objects from Linq2SQL directly; you get them from the web services. If you had a Controller layer that talked to Linq2SQL, you could replace that layer with controllers that talked to the web services. It sounds like a minor difference; you always have to change something. But, now you're using EXACTLY the same UI on the mobile and desktop apps, so changes at THAT layer don't have to be made twice just because the two layers get data different ways.
This is a great question that I have been mulling over with our catalog app for a year now. A specific instance for me might help you with the pattern.
I have a page to display the contents of a shopping cart. In the 'early days' this page had a grid populated by the results of a SQL stored procedure that, given the order number, listed the items in the cart.
Now I have a 'cart' BLL object which contains a collection of 'row' objects. The grid is the same, but the data source is the cart's rows.
Why did I do this? Initially, not becuase of any fancy design patterns. I had so many special cases to handle based on fields in each row AND I had other places I needed to show the same cart-content data, it just made more sense to build the objects. Now a cart loads from a repository and my pages have no idea what that repository does. Heck, for testing, it's hard-coded cart data.
The cart then uses a repository to load up the rows. Each row has logic to maniuplate itself, not knowing where the data came from.
Hopefully that helps?
scenario:
you need to update 2 fields of a customer
you don't have a method UpdateCustomer yet anywhere in your project
Should you create a method called UpdateCustomer(Customer customer) that can take in a full customer object and just do an all update to all fields
or
for example (obviously the name is just for posting here) create an UpdateCustomer2Fields(string month, string year) and just update those 2 fields
I could imagine a shitload of UpdateCustomerThis
UpdateCustomerThat
but if I just expose one UpdateCustomer, I can pass it a customer object and have it update anything and use this anywhere.
Good, Bad? which way to go.
You should just update all fields, unless there is a reason not to, to reduce your maintenance headaches.
Reasons not to update all fields. These are all very specific to environment, and are only valid if you've observed them in your situation.
The vast majority of your transactions are updates, resulting in a heavy burden due to unnecessary data being passed over the network.
A business or legal compliance requires you to log exactly what users changed which exact data with every transaction (these do exist). However, depending on the environment it may be best to log this at the database server.
Some users should not have update access to some fields. This is architecture specific and relates to how you expose your functions. If someone must have certain credentials to update specific information, then generally, you will not want to have every transaction update everything. This can be dynamic, and may result in passing in a dictionary of fields to update (or a myriad of other choices). I typically run into this with tiered architectures using services with multiple consumers that have different access rights.
Did I miss any?
Generally, the answer is just pass the entire object.
Create a method called UpdateCustomer(Customer customer) that can take in a full customer object and just do an all update to all fields.
Keep it simple. Now you can spend your time on bigger problems.