Stateless Asp.Net MVC disables some features of EF - asp.net-mvc

I am reading a book on ASP.NET MVC, where the author has mentioned that due to the stateless nature of ASP.NET MVC some of the features in Entity Framework are disabled.
With that in mind, it is best to abstract the data access layer. The Repository pattern is one of the most used patterns for managing data abstraction.
I am curious to know, what are the features of EF will be disabled, if Repository pattern is not used for data abstraction.

I am reading the same Exam 70-486 book.
Entity Framework can't have the DbContextObject (the old ObjectContext) object live for the whole user session, this means that Entity Framework can't track changes to the entity object in a web application.
The solution is to create a new DbContextObject object each time we need to make some operations against a database.
However, this solution is causing one problem, when we need to delete or update a record with the new instance of DbContextObject. One first solution is to retrieve first the object that you are trying to modify, and only then do the necessary changes. Another solution would be to mark the entity state as modified (
context.Entry(entity).State = EntityState.Modified;) without the need to retrieve the entity first

In particular, entity tracking is not very useful, because you have new object instance on each request. Workaround for update is:
var entity = new Entity();
entity.Id = id;
content.Entry(entity).State = EntityState.Modified;
context.SaveChanges();

Related

An entity object cannot be referenced by multiple instances of IEntityChangeTracker error when trying to save changes to multiple types of entities

I have a controller action where I am attempting to both create a new object in the database, of type FantasyTeam, and also modify an existing object, of type User. However, when the action is called I am receiving a System.InvalidOperationException exception, with the explanation of:
An entity object cannot be referenced by multiple instances of
IEntityChangeTracker.
My code is below.
public ActionResult Create([Bind(Include="ID,FantasyTeamName")] FantasyTeam fantasyteam)
{
if (ModelState.IsValid)
{
var CurrentUser = UserManager.FindById(User.Identity.GetUserId());
fantasyteam.OwnerID = CurrentUser.Id;
CurrentUser.HasTeam = true;
db.FantasyTeams.Add(fantasyteam);
db.Entry(CurrentUser).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Dashboard", "Application");
}
return View(fantasyteam);
}
The Controller Action takes the new FantasyTeam object as a parameter from the View where the team details are selected by user. I then find the currently logged in user and set the OwnerID of the team to match the UserID of the owner, as my Foreign Key. I then go to add the new FantasyTeam to the database and also modify the User record in the database, changing the Boolean HasTeam to true. The adding of the new team works fine on its own... I have been getting the exception once I tried to modify the User object as well.
I have searched on StackOverflow for this exception, and have found many related issues, but I couldn't find a way to apply the other resolutions to my problem. In some cases the issue was that the developers were using two separate data contexts when they should have just been using one, but I don't think that would apply to me here.
Could someone offer insight as to what might be going wrong here?
Thanks!
According to Linq to SQL DataContext Lifetime Management the main causality of the problem comes from the below reason.
Linq to SQL uses a DataContext to manage it's access to the database as well as tracking changes made to entities retrieved from the database. Linq to SQL has a persistent approach to managing its 'connection' to the database via this data context and it basically assumes that you use a single DataContext to make all of your data related access. This doesn't mean that it makes persistent connections to the database, but means that the DataContext instance maintains state about active result sets, which is especially important if change tracking is on which is the default.
The comment posted by haim770 was the answer - I didn't realize that the UserManager object was using a different context than the db object was using. Once I changed the UserManager object to use the same context as db, my code works as intended.

Use data annonations in ASP.NET MVC using DDD

I've started to develop ASP.NET MVC application using Entity Framework and I wish to use DDD. It's my first time using DDD in ASP.NET (used until now in PHP), so I'm little confused.
I'm using code-first approach, so I'm creating my entites in the core and then the DbContext in the Infrastructure.
My questions is about data annotations: Is it OK to annonate the entities in the core? with Required, DataType, etc. or I have to create entries with pure C# validation (in the setters and getters) and then create a map objects for the database creation?
For example, I got:
public class Account
{
public string AccountName { get; set; }
}
Can I annonate the AccountName with [Required] or I need to create a map class which will just reflect the exact same properties in the Account class but will have attributes and that will be the class that I'll use in Entity Framework DbContext?
Thanks!
Neither.
Your entities should have barely any public getters or setters. Domain model is a behavioral model, not a data model. Your entities should have private fields and methods that changes the entity state. Those methods should have a business meaning and should protect entities invariants (validate input). For example - we have UserAddress and want to change it. Is it just user.Address = newAddress? NO. What's the meaning of changing that? Maybe your User want to FixMistypedAddress(str). Or maybe your UserMoved(newLocation)? Different business rules may apply tho those scenarios. For example when UserMoved() we want to send him a champagne bottle, but not when he just fixed a typo. You should already see that there is no use of data annotations here because we don't just set properties but we do meaningful operations.
Entities should always be valid. That mean there should be no way to put it in an invalid state. Data annotations only allow you to check whether the object is valid or not. They not guarantee is will be valid all the time.
IMO Data annotations are fine for:
Using Entity Framework in a CRUD application (no DDD applied)
In DTO or ViewModels. In other words - for validating user forms, not entities.
So the first quiestion for you is: Are you doing CRUD or DDD?
I'd say either way is fine.
If you want a more pure approach you would create a buddy class that has the metadata on it however it is also acceptable to put it directly on the domain class.
In the end it comes down to how much you want to remain "pure" and how much extra work you want to put into maintaining buddy classes, not to say that it is a bad thing.

ASP.NET MVC -> WCF -> NHibernate, how to efficiently update entity with data from viewmodel?

A week back, I had an ASP.NET MVC application that called on a logical POCO service layer to perform business logic against entities. One approach I commonly used was to use AutoMapper to map a populated viewmodel to an entity and call update on the entity (pseudo code below).
MyEntity myEntity = myService.GetEntity(param);
Mapper.CreateMap<MyEntityVM, MyEntity>();
Mapper.Map(myEntityVM, myEntity);
this.myService.UpdateEntity(myEntity);
The update call would take an instance of the entity and, through a repository, call NHibernate's Update method on the entity.
Well, I recently changed my logical service layer into WCF Web Services. I've noticed that the link NHibernate makes with an entity is now lost when the entity is sent from the service layer to my application. When I try to operate against the entity in the update method, things are in NHibernate's session that shouldn't be and vice-versa - it fails complaining about nulls on child identifiers and such.
So my question...
What can I do to efficiently take input from my populated viewmodel and ultimately end up modifying the object through NHibernate?
Is there a quick fix that I can apply with NHibernate?
Should I take a different approach in conveying the changes from the application to the service layer?
EDIT:
The best approach I can think of right now, is to create a new entity and map from the view model to the new entity (including the identifier). I would pass that to the service layer where it would retrieve the entity using the repository, map the changes using AutoMapper, and call the repository's update method. I will be mapping twice, but it might work (although I'll have to exclude a bunch of properties/children in the second mapping).
No quick fix. You've run into the change tracking over the wire issue. AFAIK NHibernate has no native way to handle this.
These may help:
https://forum.hibernate.org/viewtopic.php?f=25&t=989106
http://lunaverse.wordpress.com/2007/05/09/remoting-using-wcf-and-nhibernate/
In a nutshell your two options are to adjust your service to send state change information over the Nhibernate can read or load the objects, apply the changes and then save in your service layer.
Don't be afraid of doing a select before an update inside your service. This is good practice anyway to prevent concurrency issues.
I don't know if this is the best approach, but I wanted to pass along information on a quick fix with NHibernate.
From NHibernate.xml...
<member name="M:NHibernate.ISession.SaveOrUpdateCopy(System.Object)">
<summary>
Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with
the session, it will be loaded. Return the persistent instance. If the
given instance is unsaved or does not exist in the database, save it and
return it as a newly persistent instance. Otherwise, the given instance
does not become associated with the session.
</summary>
<param name="obj">a transient instance with state to be copied</param>
<returns>an updated persistent instance</returns>
</member>
It's working although I haven't had time to examine the database calls to see if it's doing exactly what I expect it to do.

EF4: Difference between POCO , Self Tracking Entities , POCO Proxies

Can someone point me the difference between POCO , Self Tracking Entities , POCO Proxies?
Actually, I am working Entity Framework 4.0 and POCO(Repository Pattern) and whenever I do some changes in the POCO and call ObjectContext.Savechanges then it reflects to the DB.
My question is,
How does the Context persist the change to the DB since it is not tracked?
Does the Context generates the tracking info on the fly for POCO?
Sample Code I am using,
IEFRepository<Category> catRepository = new EFRepository<Category>();
Category c = catRepository.FindOne<Category>(x => x.Name == "Paper");
c.Name = "Paper";
catRepository.SaveChanges(System.Data.Objects.SaveOptions.None);
Self tracking entities are not POCOs. On the contrary, they are very much persistence-aware. More so than EntityObject entities, even. What makes them unique is the changes can be tracked even when they are not attached to an ObjectContext.
"Pure" POCOs, as you say, make change tracking difficult. Really, the only thing you can do is compare snapshots of the object. The object context has a DetectChanges method for this.
With a pseudo-POCO proxy, what you really have is a type which looks (almost) like a POCO at compile time and like a non-POCO at runtime. I say "almost" because at runtime you will get an instance which is a subtype of the compile-time type. Because of this, any properties for which you want to track changes must be non-private and virtual. Similar restrictions apply to lazy loading. You can read more about this in this series of articles on the ADO.NET team blog.

ASP.net MVC: Where in my design should I create/declare entity keys?

When creating a new entity object that has a foreign key value I need to create a new Entity key (Entity Framework in .net 3.5) for the object, but I'm having trouble deciding where in my application I should do this.
Right now when I create a new record with a foreign key, I create the entity key in the controller (in this case a user ID pulled from a membership provider), assign it to the object and pass it to the repository service layer.
Are there any problems with this, or should I be passing the object plus the user ID to the repository service layer and have it deal with the entity key creation? Passing one object seems cleaner, but having multiple controllers assigning keys this way makes me nervous. Thanks.
I think this is a matter of separation of concerns. A repository is concerned with retrieving and adding/changing/removing entities. It shouldn't be responsible for building entities. Conversely, the controller really shouldn't be responsible for building entities either (a controller should to the bare-bones amount of work required to push data to a view, and handle commands from a view delegate those commands to business logic...business logic belongs elsewhere (like a domain).) In all honesty, you should create an EntityBuilder of some sort to handle the process of creating entities. You would pass the object plus user ID to a builder, which would then provide you with a fully built entity that could then be passed on to a repository.
EDIT:
Even with your change from 'Repository' to 'Service Layer', the principal remains the same. Delegate the process of building your entity to a dedicated builder, and maintain your separation of concerns.

Resources