EF CTP4 when to call context.SaveChanges - entity-framework-4

I'm trying to replicate many of the practices we use with NHibernate in EF CTP4.
Currently we have a generic repository interface (CTP4 actually makes this quite easy with DbContext.Set).
We are passing in the context and using StructureMap to scope it per HttpRequest.
With NHibernate we pass in ISession (again created using StructureMap) but use an ActionFilter (UnitOfWork) to commit the transaction at the end of the request.
Do we have equivalent transactions in EF CTP4? If not, should I use the same filter to call context.SaveChanges() or just do this inside the repository.
On a side note, what's the easiest way of testing to see whether an entity is new or not. With NH we have the luxury of just calling ISession.SaveOrUpdate. Note that all my entities use a Guid identifier. Perhaps a check for default(Guid)?
Thanks.

I know this is a late answer that you will have figured out by now but i guess its useful for people searching. Rob conery has a great post on using actionfilter and Ef to create transactions per request scope.
Rob C Article
Oh and yes I would create an UpdateInsert() method on a generic repository that test for default(Guid).

Related

Where is the constructor of Model in ASP.NET Core MVC with EF Core

I am working on ASP.NET Core MVC Application that uses Entity framework Core. So everything seemed ok but somehow i came up with an interesting question and couldn't find the answer in the web.
Here what i know.
When we use EF Core it gives us ability to represent database tables as classes and to work with them. I have a CONTEXT.cs class that creates entities, gives them properties corresponding to database.
Here is my question
If a model is a class then where is the constructor? Or that is done when i "create" something and the whole info comes to controller like this( [Bind("id", "name") ]Materials materials) and data is simply being added to context
Thanks in advance. Please correct me if i'm writing anything wrong
I think that this link will answer the first part of your question:
https://learn.microsoft.com/en-us/ef/core/modeling/constructors
And about binding models which coming from controller actions. At least in previous versions, the data was set through public field setters that can implement complex logic. For example, a boolean setter can actually add a value to a private List when assigning a 'true' value.

Stored Procedures and Entity Framework 5

I'm using Entity Framework 5, and I reverse engineer code first the database I'm using, and then I added an ADO.NET Entity Data Model so that I can use Stored Procedures as reverse engineer code first didn't provide the use of sprocs. Is this the only way to access sprocs?
Also, I realize that after the reverse engineer code first process is done a bunch of classes (tables from the database) are created but as soon as I add the ADO.NET Entity Data Model, most of the classes go away. Does anybody know why?
DbContext.Database property exposes useful methods
http://msdn.microsoft.com/en-us/library/system.data.entity.database(v=vs.103).aspx
ExecuteSqlCommand( string, object[] )
http://msdn.microsoft.com/en-us/library/system.data.entity.database.executesqlcommand(v=vs.103).aspx
SqlQuery<TEntity>( string, object[] )
http://msdn.microsoft.com/en-us/library/gg696545(v=vs.103).aspx
There is a pattern that you can follow to create or support store procedures with the code first approach. here is a link that you can use to follow this:
http://www.codeproject.com/Articles/179481/Code-First-Stored-Procedures
In few words you need to do the same that you do with model first, create a class that supports the inputs and a class that supports the result set.
And about the Data Entity Model and missing classes. You need to consider that you only can have one approach in a project: code first/(model first/database first), so this could be the reason why you are not seeing those clases.
You can use Context.Database.SqlQuery to run SP.

MVC4 Form verification, maybe Action Filters

I need to add two kinds of verification to a comment form I’ve built. Some type on human verification and some type of email verification. Would putting these into Action Filters be a good way to go?
I don’t want to use Google’s recapture, I don’t like using it myself when I’m asked too and I have seen some other clever options around the place but that’s for another thread.
Is this the type of thing I should/could put into Action Filters???
Cheers,
Mike.
I found the answer to this thanks to a great guy at asp.net, so I will quote him, CodeHobo said,
“You implement this by using the concept of a buddy class. Basically you create another class with public properties that match the properties of your EF model. You apply the validation attributes to your "buddy class".
Then create a partial class to match your EF model (EF generates partial classes for all models). You add an attribute to your partial that points to your "buddy class". Basically you are telling mvc to use the validations in the associated class instead of the EF model.
Take a look at this
http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validation-with-the-data-annotation-validators-cs”
This worked for me and was amazingly simple to implement thanks to MVC.

Advice on POCO Validation with ASP.NET MVC/Entity Framework

Here's the scenario:
ASP.NET MVC2 Web Application
Entity Framework 4 (Pure POCO's, Custom Data Context)
Repository Pattern
Unit of Work Pattern
Dependency Injection
Service Layer mediating Controller -> Repository
So basically, all the cool stuff. :)
Flow of events for a basic UI operation ("Adding a Post"):
Controller calls Add(Post) method on service layer
Service layer calls Add(T) on repository
Repository calls AddObject(T) on custom data context
Controller calls Commit() on Unit of Work
Now, i'm trying to work out where i can put my validation.
At this stage, i need two types of validation:
Simple, independant POCO validation such as "post must have a title". This seems a natural fit for Data Annotations on the POCO's.
Complex business validation, such as "cannot add a comment to a locked post". This can't be done by Data Annotations.
Now, i have been reading "Programming Entity Framework, Second Edition" by Julie Lerman (which is excellent BTW), and have been looking into hooking into the SavingChanges event in order to perform "last-minute" validation. This would be a nice way to ensure validation always happens whenever i do "something" (add, modify, delete), but it's also a little late IMO (as the items are already in the state manager) - so what can i do if validation fails, remove them?
I could of course make my POCO's implement an interface (say "IValidatable"), and call a method on this interface during this event.
But this seems "too late" for business validation - is this the consensus?
I'm basically looking for guidance here, i'm trying to design a re-usable, intelligent validation scheme for complex business logic, given my above architecture.
Another curve-ball for you - as you know, POCO's with EF mean the POCO's have all the properties on the DB - so i might have a "PostID" property, with get/set accessors (as EF needs to get/set these properties).
But the problem is, "PostID" is an identity column, so how do i protect the field from being explicity set? E.g if i (for some reason) do the following:
var post = service.FindSingle(10);
post.PostId = 10;
unitOfWork.Commit();
This will throw a SqlException. How can i prevent this? I can't "hide" the property (make it private, or even internal) as the POCO's are in a seperate assembly to the Repository.
A note on validation - i'm planning to create custom exceptions (deriving from Exception). So when validation fails, i need to throw these exceptions.
That way, i can code something like this on my controller:
[HttpPost]
public ActionResult AddPost(Post post)
{
try
{
IUnitOfWork uow = new UnitOfWork();
postService.Add(post);
uow.Commit();
}
catch(InvalidPostOperation ipo)
{
// add error to viewmodel
}
}
Will i have to manually do validation on the service layer everytime i do an Add? Then how can i handle Save? (as this is on the Unit of Work, not the service layer).
So to prevent this from being a "all over the place" question, here are my questions:
Simple POCO validation - should this be done with Data Annotations? Pros/cons/gotchas?
Under what circumstances (if any) should we be hooking into the SavingChanges event of the EF Data Context in order to provide validation?
Where should i be performing complex business validation? In the service explicity, or a method on the POCO's (which i can call from service). How can i create an intelligent/reusable scheme?
How can we "hide" auto-generated properties of POCO's from being tampering with?
Any thoughts would be most appreciated.
Apologize if this post is "too long", but it's an important issue and one that can be solved in many ways, so i wanted to provide all the info in order for the best possible answer.
Thanks.
EDIT
The below answer is helpful, but i'm still (ideally) looking for more thoughts. Anyone else?
Well like you said, DataAnnotations is not appropriate for all situations. Cons are mainly complex validation (multiple property and multiple property different object) in my experience.
If i were you, i would leave business/domain validation out of the Data Layer (EF) as much as possible. If there is a Data Layer validation scenario, then fine (eg. validating complex parent/child relationships - this is purely DB stuff).
Yes, the complex business validation should be in the Service Layer or in the Model Objects (attached, via partial classes or some inheritance approach: interfaces/derived classes). There's debate about this between ActiveRecord people, Repository Pattern people and DDD people, but go with what works for you, is simple and will enable rapid deployment and low cost application maintenance. This is a simple example of how you might attach more complex validation to domain objects yet is still compatible with the DataAnnotations interface and thus is 'MVC friendly'.
Good question. -one i have not found a solution i'm 100% happy with yet. I have played with the idea of private setters and it's not great. Have a quick read of this summarized Evans DDD book. It's great quick read and it might provide some insight about the purpose and difference between Model Objects and Value Objects. This is where i think object design will mitigate the problems your having with the property "tampering" (as you call it) but without fixing the property visibility. Ie, another solution might lie elsewhere. Hope this helps.
Hey, probably a bit late but here goes anyway...
It all depends on your architecture, i.e. Is there a logical seperation, in your application: UI, Service Layer, Repository Layer. If you are hooking onto the Save event, how exactly will that be done? From what I observed you would be calling the repository Layer for Persistance only right? However you are hooking onto the save event, giving control back to the Service Layer/ Business Layer whatever then forcing the save through right?
I personally feel the Service layer/ Business Layer should take care of it in completion then say, hey mr repo layer -> save this object.
With regards to validation, Data Annotations should be used with the UI, so simple valiation like [Required] etc, this will be helpful with the Client Side validation but complex business logic or complex validation should be hooked into the service layer/ business layer, that way it is reusable across all entities/ objects/ POCOS etc.
With regards to preventing certain private fields not being tampered with... only allow your service layer/ business layer to actually set the object that will be persisted (yes i mean :) ...) hand coding it, I felt this was the safest option for me anyway, as I will simple do:
var updatedpost = _repo.GetPost(post.postid);
updatedpost.comment = post.comment;
updatedpost.timestamp = datetime.now;
Kind of wasteful but that way your buseinss layer takes control, however this is just my experience I may be wrong, I have read a lot into model binding, validaiton and other stuff however there seemed to be cases where things never work as expected e.g. [Required] attribute (see Brad WIlson's) post.

DataContextProvider

Going from the example given here...
http://ericswann.org/blog/archive/2009/04/06/linq-to-sql-datacontext-provider-revisited.aspx
I'm trying to use the datacontext between the MembershipProvider and the RoleProvider.
For instance, when I call Membership.GetUser(XXXXXX) in the RoleProvider, I get an error because it pulls an item from one datacontext and tries to use it (hence the need for the repository)
But I am ...really stupid, and this is some pretty advanced stuff. Seeing as how I do not get to 'instantiate' the Providers, does anyone have an idea how I might go about using this?
First of all pick your datacontext caching strategy. Use DataContextThreadCache if you're working in winforms, where the context is cached in your running thread context. Use DataContextWebCache if you're working with web apps where the context is cached in HTTP run-time cache.
To register your datacontext look at DataContextProvider.RegisterDataContext and its overloads. Here is an example:
DataContextProvider.RegisterDataContext<YourDataContextType, YourCacheStrategyType>(contextKey, contextConnectionString)
contextKey: is the key you will use to retrieve your data context with.
contextConnectionString: is the connection string for your data context.
This call will use the type of DataContext you specified to create an new instance of it. It will then cache it using the specific caching strategy you specified also. This should probably be called somewhere during the initialization phase of your application. Your repository can then use GetDataContext as outlined in that blog post to get the context instance.

Resources