I'm getting ready to start a new project and I've been researching the entity framework. My question is what is the best strategy for validating the entities? Other projects I've worked on have used attributes for most of the validation, but obviously this is not possible in the entity framework. Is the only way to do this by handling the partial methods in the property setters? All advice is much appreciated.
I have not actually used the Entity framework before but a quick search indicates that you have several options.
1) Validate at another layer in your application
Always an option, I just thought I would throw it out there explicitly.
2) Hook into the OnChanged events of the Entity then perform validation
Likely brittle and would become confusing/slow after if you have many different properties things that can change for each entity.
3) Implement partial methods to validate property changes
According to this post and this walkthrough there are partial methods available for validation. This seems like your best option as it is not very intrusive and you can selectively implement the validation you want.
I hope that helps. Good luck.
In .NET 4, there is going to be out-the-box validation support in Entity-Framework.
Check out: http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx
So don't work to hard on implementing too complex validation logic...
If you use ASP.NET MVC, then you could use Validation Application Block or the System.ComponentModel.DataAnnotations. The articles Using Data Annotations and Using Application Block show how to do them using Linq, but the usage with entity-framework should be similiar.
We have overrident the object context and intercept the SaveChanges() method
public abstract class ValidationObjectContext : ObjectContext{
...
public override int SaveChanges(SaveOptions options){
ValidateEntities();
return base.SaveChanges(options);
}
}
That way the validation is left until the last minute before the connections are made but after you are (expecting) to be happy with the graph and ready to commit, (as opposed to other options to validation on any change, since some complex rules like those we have are only valid after several properties are set.). We have two levels of validation, Basic Property validation, things like string length, nullability etc. And Business Logic validation, which might require checking rules across multiple objects, possibly hitting the database to confirm.
If you are using WPF or Windows Forms then you might implement the IDataErrorInfo interface.
The BookLibrary sample application of the WPF Application Framework (WAF) project shows how entities created by the Entity Framework can be validated.
Consider implementing IValidatableObject in your entities.
Related
This isn't a specific coding question, but rather I'm looking for some advice on how to approach a problem of mine. I have a Silverlight 5 application that uses WCF to do most of its operations - I like the control it gives me compared to RIA. A lot of these WCF methods take Entity Framework objects as arguments, with extra logic and authorization handled on the server side. This works fairly well and I have a nice little framework that lets me pass objects back and fourth, while knowing that the server will only let certain things be changed depending on the user's permissions.
There are a few things about RIA I like though. I use it to populate datagrids because of its easily generated filters, ordering, etc. I've used RIA more heavily for projects in the past and I mostly like its form generation and validation metadata abilities. I like that, with a class, it will easily make me a form with all the textboxes, combodoxes, checkboxes, labels, etc, as well as with two way binding and validate on error set up for each of these. Tying in with validation, because I'm using Entity Framework objects, I can't just stick DataAnnotations on the ORM generated classes, so the autogenerated metadata classes of RIA are very useful in that regard.
The issue seems to be that these objects are incompatible. I can't use RIA generated classes with my methods that are expecting Entity Framework objects. I can't use RIA to generate the forms and then bind them to my regular entity objects because then there's no automatic validation. Does anyone have any ideas on how I can marry these two? I'm open to thoughts/suggestions.
The form generation and validation magic is not tied to RIA Service client's EntityObject base class.
If you annotate your WCF client's proxy classes with Validation Attributes, you can get more or less the same result.
If you implement IEditableObject, then the datagrid will restore modified data when you hit ESC.
Through careful use of .shared.cs files, and linked source files, you can have most of the server side and client side code being shared.
To achieve even more flexibility, you will need to start crafting your own T4 templates.
While working in ASP.NET MVC, I often find myself defining a basic ViewModel which all properties are but a small subset of the actual Entity model. I then use AutoMapper to transform my objects properly into and out of the Entity model. This works great, and separates my concerns nicely. However, I'm thinking that someone by now has made a tool to make this process easier! All the repetitive typing while creating my ViewModels inevitably leads to typos and some frustration.
What tools, if any, do you use to address this issue?
Thanks!
Edit: I don't mind decorating my properties with the appropriate UI hints, validators, etc. I just hate defining the same propery names again and again!
You could consider using T4 templating, see this MSDN magazine article to get started. You could create a template that uses reflection to get the properties of your Model, and generate ViewModel from this.
Not sure if there's a "offical" name, but by DataContext I mean an object which transparently maintains objects' state, providing change tracking, statement-of-work functionality, concurrency and probably many other useful features. (In Entity Framework it's ObjectContext, in NHibernate - ISession).
Eventually I've come to an idea that something like that should be implemented in my application (it uses mongodb as back-end, and mongodb's partial updates are fine when we're able to track a certain property change).
So actually, I've got several questions on this subject
Could anyone formulate requirements to DataContext? - what's your understanding of it's tasks and responsibilities? (The most relevant I've managed to find is Esposito's book, but unfortunately that's at about msdn samples level).
What would you suggest for changes tracking implementation? (In simplest way it's possible to track changes "manually" in entities, but requires coding and mixes dal with business logic, so I mostly interested in "automatic" way, keeping entities more poco).
Is there way to utilize some existing solution? (I hoped nhibernate infrastructure would allow plugging-in custom module to work with mongo behind the scene, but not sure if it allows working with non-sql dbs at all).
The DataContext (ObjectContext or DbContext in EF) is nothing else than an implementation of the Unit of Work (UoW)/Repository pattern.
I suggest you Fowler's book on Patterns of Enterprise Application Architecture in which he outlines the implementation of several persistency patterns. That might be a help in implementing your own solution.
A DataContext basically needs to fullfil the job of a UoW. It needs to handle the reading and management of objects that are involved in a given lifecycle (i.e. HTTP request), s.t. there are no two objects in memory that represent the same record on the DB. Moreover it needs to provide some change tracking for performing partial updates to the DB (as you already mentioned).
To what regards change tracking, I fully agree that polluting properties with change events etc is bad. One of the recent templates introduced in EF4.1 uses Proxies to handle that and to give the possibility to have plain POCOs.
Answer to quetion 2: To make POCO classes work, you will need to generate code at run-time, possibly using System.Reflection.
If you analyse EntityFramework, you will see that it requires virtual properties to do change-tracking... that is because it needs to create a generated class at run-time, that overrides each property, and then adds code to tell the DataContext when someone changes that property.
EntityFramework also generates code to initialize collections, so that when someone try to do operations like Add and Remove, the collection object itself knows what to do.
OK,
This is probably not simple but I figured I would throw it out there:
I get the idea of extending an Model-First entity in EF with a partial class to add data annotation elements somthing like this:
[Required]
string MyString {get;set;}
However, if I am in a multi-tenant system where I may want to customize which fields are actually required when passed to the end client can I dynamically set the annotation depending on how the client has configured the setting, say in another table for instance?
Update: In the multi-tenant system there are at least two databases. One that stores system configuration information. In addition each customer would have their own individual database. The system DB controls routing and selecting the proper customer database from there.
Any insights or ideas anyone has on how to accomplish this would be great!
Thanks,
Brent
If you are using EF 4.1, you could create different DbContexts, referencing the same entities, but provide different mappings using the Fluent Api.
Here is a link to a video that describes using the api.
Fluent Api
Note: Your database would need to be setup to accommodate all the different configurations. For example, if in one context, "FirstName" is required, and in another it is not, your db should allow NULL in order to cope with both situations.
You can't change attributes dynamically.
One option would be to crate the types dynamically, probably inheriting some class (or implementing an interface), that you actually work with. Although I'm not sure this would work with EF.
Another possibility is if EF had another way you could tell it the same thing, but I don't know EF much, so I can't tell if something like that exists.
I'm at a bit of a loss here.
I have a one-to-many relationship between Project and Task and another between Task and TaskEvent.
A Task only exists in the context of a Project and once assigned to a Project can't be changed to belong to another Project.
A business rule states that a Task can only be deleted, and therefore removed from the collection of Tasks that belong to a certain project, if the Task has no TaskEvents captured against it.
How do I specify this in Entity Framework? I'm using Self-Tracking entities, but actually I'm at a loss as to where to define this kind of rule in general. We have other rules that are db ignorant, but how does one define a business rule, preferably that exists in isolation from the entity classes as they are regenerated, as a class of their own with a single responsibility?
I'm thinking I'll have to implement some sort of validator that can use reflection to pick up these 'rule' classes based on the type of the object being validated and then have them each perform their validations.
But how do I push the object context into that? Should my validator have an instance of the object context and then pass it through to each rule as it is executed?
And even more flustering, how do I detect the deletes? Will I have to call up the old version of the Project and do a comparison of it's old tasks and current tasks and then check all the deleted ones to make sure they have not TimeEvents captured?
What are the drawbacks to this method and what else can you suggest?
EDIT: I should specify that we're using an n-tier design and both the client apps(MVC and Silverlight) hit WCF services to do anything useful. This is obviously the layer we want to implement the validation in, although if we could use those rules that aren't db specific on the clients that would be great. We're using DataAnnotations for those validations at present.
Thanks
Have a look at this.
Since you are using the n-tier design , my suggestion is to use the EF as a ORM layer rather than a full substitute for domain model. You should create a separate BLL layer that contains business rules and map the domain model to the EF classes. If the mapping is not complicated it can be done manually else you can use tools such as Automapper to perform the mapping for you.
We ended up using a service layer which encapsulated the rules and validated entities based on rule contexts.
For each action there was a context and a set of rules that were associated through the use of an attribute. All associated rules could therefore target the entity of a specific type required by the service action.
The rules were identified using reflection and tested on the service call.
Entity Framework entities still acted as a slightly thinner domain model than I would have liked but we never ran into serious issues and the tracking provided by EF actually helped make some previously impossible rules easy.