Is it good to use a static EF object context in an MVC application for better perf? - asp.net-mvc

Let's start with this basic scenario:
I have a bunch of Tables that are essentially rarely changed Enums (e.g. GeoLocations, Category, etc.) I want to load these into my EF ObjectContext so that I can assign them to entities that reference them as FK. These objects are also used to populate all sorts of dropdown controls. Pretty standard scenarios so far.
Since a new controller is created for each page request in MVC, a new entity context is created and these "enum" objects are loaded repeatedly. I thought about using a static context object across all instances of controllers (or repository object).
But will this require too much locking and therefore actually worsen perf?
Alternatively, I'm thinking of using a static context only for read-only tables. But since entities that reference them must be in the same context anyway, this isn't any different from the above.
I also don't want to get into the business of attaching/detaching these enum objects. Since I believe once I attach a static enum object to an entity, I can't attach it again to another entity??
Please help, I'm quite new to EF + MVC, so am wondering what is the best approach.

Personally, I never have any static Context stuff, etc. For me, when i call the database (CRUD) I use that context for that single transaction/unit of work.
So in this case, what you're suggesting is that you wish to retrieve some data from the databse .. and this data is .. more or less .. read only and doesn't change / static.
Lookup data is a great example of this.
So your Categories never change. Your GeoLocations never change, also.
I would not worry about this concept on the database/persistence level, but on the application level. So, just forget that this data is static/readonly etc.. and just get it. Then, when you're in your application (ie. ASP.NET web MVC controller method or in the global.asax code) THEN you should cache this ... on the UI layer.
If you're doing a nice n-tiered MVC app, which contains
UI layer
Services / Business Logic Layer
Persistence / Database data layer
Then I would cache this in the Middle Tier .. which is called by the UI Layer (ie. the MVC Controller Action .. eg. public void Index())
I think it's important to know how to seperate your concerns .. and the database stuff is should just be that -> CRUD'ish stuff and some unique stored procs when required. Don't worry about caching data, etc. Keep this layer as light as possible and as simple as possible.
Then, your middle Tier (if it exists) or your top tier should worry about what to do with this data -> in this case, cache it because it's very static.

I've implemented something similar using Linq2SQL by retrieving these 'lookup tables' as lists on app startup and storing them in ASP's caching mechanism. By using the ASP cache, I don't have to worry about threading/locking etc. Not sure why you'd need to attach them to a context, something like that could easily be retrieved if necessary via the table PK id.

I believe this is as much a question of what to cache as how. When your are dealing with EF, you can quickly run into problems when you try to persist EF objects across different contexts and attempt to detach/attach those objects. If you are using your own POCO objects with custom t4 templates then this isn't an issue, but if you are using vanilla EF then you will want to create POCO objects for your cache.
For most simple lookup items (i.e numeric primary key and string text description), you can use Dictionary. If you have multiple fields you need to pass and back with the UI then you can build a more complete object model. Since these will be POCO objects they can then be persisted pretty much anywhere and any way you like. I recommend using caching logic outside of your MVC application such that you can easily mock the caching activity for testing. If you have multiple lists you need to cache, you can put them all in one container class that looks something like this:
public class MyCacheContainer
{
public Dictionary<int, string> GeoLocations { get; set; }
public List<Category> Categories { get; set; }
}
The next question is do you really need these objects in your entity model at all. Chances are all you really need are the primary keys (i.e. you create a dropdown list using the keys and values from the dictionary and just post the ID). Therefore you could potentially handle all of the lookups to the textual description in the construction of your view models. That could look something like this:
MyEntityObject item = Context.MyEntityObjects.FirstOrDefault(i => i.Id == id);
MyCacheContainer cache = CacheFactory.GetCache();
MyViewModel model = new MyViewModel { Item = item, GeoLocationDescription = GeoLocations[item.GeoLocationId] };
If you absolutely must have those objects in your context (i.e. if there are referential entities that tie 2 or more other tables together), you can pass that cache container into your data access layer so it can do the proper lookups.
As for assigning "valid" entities, in .Net 4 you can just set the foreign key properties and don't have to actually attach an object (technically you can do this in 3.5, but it requires magic strings to set the keys). If you are using 3.5, you might just try something like this:
myItem.Category = Context.Categories.FirstOrDefault(c => c.id == id);
While this isn't the most elegant solution and does require an extra roundtrip to the DB to get a category you don't really need, it works. Doing a single record lookup based on a primary key should not really be that big of a hit especially if the table is small like the type of lookup data you are talking about.
If you are stuck with 3.5 and don't want to make that extra round trip and you want to go the magic string route, just make sure you use some type of static resource and/or code generator for your magic strings so you don't fat finger them. There are many examples here that show how do assign a new EntityKey to a reference without going to the DB so I won't go into that on this question.

Related

complex hierarchy updates based on form input

I am trying to understand the best way to work with complex hierarchies of objects that i manipulate based on data on forms in Grails.
I cannot use the command object as my form is dynamic (users can add any number of records). I am told we should parse the params in controller and let services do the transaction activities on the domain objects and thus reduce coupling. Sometimes this doesn't seem straightforward.
I have a few lists of child domain objects in a base domain object that is being 'updated' which means the list could have grown or reduced, meaning some domain tuples will need to be added/removed, how do i pass that information from controller to service without making a function with 8 parameters? If anyone has any strategies you've used, please share. I am sure this is not uncommon but I haven't seen any discussions on such a question.
e.g.
class DomainA {
List<DomainB> bList
List<DomainC> cList
DomainD domD
}
class DomainD {
List<DomainE> elist
}
How about relying on ajax. You might save classD and then class A, or use a command object to save both. Then with the Id´s of these two classes you might add everything else you need using ajax.

Code First - I feel I am missing the point

So to put things into perspective:
Until now i've had some experience with working with Entity Framework edmx models. The process (layer wise) would summarize to:
creating the database, having a layer of objects generated in the edmx file
having a layer of business objects (i am not sure if business is the right word) that are initialized from the edmx objects (and only the business objects are used inside my application)
in the MVC site having a layer of view model objects wherever needed (whenever generating views directly from my business objects would not work)
I am under the impression that with Code First the database layer objects (previously named edmx objects) and the business layer objects are one and the same, practically skipping a layer. That is what a colleague who had much more experience than me told me.
The problem is that i don't think this is quite applicable. Limitations of code first like scalar keys, having navigational properties inside objects, being unable to map private fields inside the DB without workarounds and being forced somewhat to have autoproperties everywhere feel that i am messing up my business objects.
Quick Example:
I have the entities of:
Team : TeamId and Description (Backend, FrontEnd etc)
Group : GroupId and Description (Developers, TeamLeaders, PMs, etc)
Status: an object that has a Team and a Group, something that is not to be kept inside the DB
User: UserId, FirstName, LastName
Employee: a user which also is part of a Team and a Group (inside it has a User property and a Status property)
The Users table will be denormalized in the sense that it will be containing all the info my User class has, but also have a TeamId and a GroupId, which will be populated only if the User is also an Employee. So basically Employee and User are mapping to the same table
This leads to some weird workarounds, since for instance in the Employee class i need to expose UserId as a primary key, and not get it through the User property's UserId (because the key needs to be scalar) which is ugly; also, even though i have a Status property inside the Employee class, i still need to have 2 additional properties (TeamId and GroupId, gotten from the Status properties Team and Group) in order to have scalar foreign keys to Groups and Teams, which again is cumbersome and feels messy. Adding inside the Group/Team class a virtual IList for navigational purposes also seems unneeded (though from what i've seen this can be skipped). Also having only auto properties for the objects seems wrong, i want to have privates instantiated by the ctor and only getters for them.
Am I not getting it ? Do i still need the additional layer even while using code first ? Is my model messed up from the beginning ? Sorry i cannot provide you with the code, but i am not home at the moment, and the code block seems very dodgy to use :D
I tend to work within the repository and service pattern(s). In my expereince, I have always found it easier to solidify what my application is going to be using (models) and how they will stored (structure). I lean on the side of building up the database with all the linking and FKs, building an EF model (EDMX), and then adding a layer on top of that as a Service/Repo layer. This way, your application always just references that Service/Repo layer, and if your EDMX breaks or you have to change the way something is calling your EDMX, you only have to fix it in one spot. Recently I have been doing a mix of the IRepository pattern mixed in with a Service class, and it seems to be meshing really well and is easy to use. Hope this clarified some for you, best of luck!

Architecture: Avoiding duplicate model/modelview code in MVC/Entity Framework Project

I'm new to the whole ASP world and I'm getting my feet wet by building a C# MVC3/EF4 project. I'm finding it hard to keep from duplicating a bunch of code in my models and view models. Consider an object Foo. I need to do the following things with Foo:
Store records of type Foo in my database.
Allow users to lookup records of an individual Foo (pass instances of Foo to a view).
Allow users to create new instances of Foo (pass instances of Foo to a form).
Let's say I also have a type Bar. A Bar contains a list of Foos. There are two requirements here:
Users can view a list of Bars.
When the user clicks on a specific Bar, it shows all of its Foos.
So, a sketch of my basic objects look like this:
class Foo
{
string FooName;
int Id;
}
class Bar
{
List<Foo> FooList;
int Id;
string Baz;
}
But when I start thinking about the different views, it begins to get messy:
The views shouldn't have any write access to any of the data members.
There's one view that takes a list of Bars but doesn't care about Bar.FooList. Let's say I also want to be good about resource management and close the DbContext as soon as possible (i.e. after the object is in memory but before I render the view). If I just pass it a list of Bars and the designer tries to access the FooList by mistake, we'll get a runtime error. Yuck!
Ok fine, I just create a distinct ViewModel for each view that has read only datamembers, no problem.
But both the database model and the form models will need to have DataAnnotations attached which say which fields are required, max length of the strings, etc. If I create separate form models and database models then I end up having to duplicate all these annotations. Yuck!
So, that's my architectural dilemma: I want to have succinct view models which restrict the views only to reading the data they are supposed to access. I want to avoid repeating data annotations all over the place. And I want to be able to aggressively free my DB resources as soon as possible. What's the best way to achieve my goals?
My advice is do NOT use data annotations in your EF entity classes. Instead, try out the fluent API. It keeps persistence concerns out of the model classes themselves. You can even define the modelbuilder stuff in an entirely different library.
As for having duplicate properties, properties are cheap:
public string MyProp { get; set; }
Not a lot of code, and you may begin to see, the viewmodels and entities need not always be exact duplicates of each other. For example, what if you want to apply [HiddenInput] to a viewmodel, to get it to render as <input type="hidden" />? Would you apply that to the entity? Why? It belongs in the viewmodel (the namespace is even System.Web.Mvc, not System.ComponentModel.DataAnnotations).
As far as duplicating error messages during validation (if you validate the MVC and EF layers separately), you can use resx resources.
As far as freeing db resources, let EF manage that. I find it's best to keep a single DbContext instance per HttpContext. You can open it up using a factory, an OnActionExecuting action filter, Application_BeginRequest, with an IoC container, or whatever. Then dispose context during OnResultExecued, Application_EndRequest, etc. Keeps things simple.

Model design in ASP.NET MVC

I am constanstly having problems with model design in MVC. Mostly all of my projects require some entities that are to be created, edited and deleted. Most of these entities have some common properties like creation date, modified date, author, modified by and in some cases even more descriptive properties are common. Because of that I have one single DB table to store them. For instance, Documents table and we store Invoices, Quotations and other business documents in it. I am using Entity Framework v4 for ORM, where we eventually end up with the Document entity.
How do I modify this entity or do I create a separate DocumentViewModel class for it to support multiple document types with common properties (so some form of inheritance or interface implementation should be implemented)? Besides identifying different document types I also need to have some types to have different Data Annotation rules (attributes).
For instance, Document table has PayDate column. Document type Invoice requires PayDate to be provided but document type Quotation does not.
This is the one single problem I am facing over and over with MVC and so far I've been handling it different every time but cannot decide how to properly handle it to achieve the maximum application maintainability and ease of development.
Have you considered making Documents entity abstract?
From the DB side, you will have Documents table containing just the fields shared by all Invoices/Quoations/etc. This field will have an IDENTITY PK - e.g DocId.
In the other tables, additional meta-data specific to that document can be stored, and the PK is a (non-IDENTITY) field DocId, which is also a FK to the Documents table.
On the EF side, Documents becomes an abstract entity, and the other entities inherit from this entity. This allows a nice OO paradigm to exist, and makes your code more robust.
We are currently using this scheme (EF4/SQL Server).
Your scenario sounds very similar to ours - consider using Abstract Classes.
EDIT
Thought i'd add a bit more info to how i've actually implemented this scenario, to put you on the right track.
As the comments to your Q state, we have little knowledge of your domain, therefore it's hard to make informed opinions. Personally, i chose to make my entity abstract, because certain functionality required a "mixed-bag" of items to be returned in one hit. There are other ways to do this of course (such as a stored procedure), but this allows a nice fluent interface between my UI (which is MVC by the way) and my service layer.
Works like this - here's how i get a single Post:
// var is strongly-typed to a "Post"
var somePost = repository.FindSingle(10);
Here's how i get a mixed-bag of Posts:
// var is strongly-typed to a "ICollection<Post>".
// "Title" is a property on my "Post" abstract POCO
var mixedBagOfPosts = repository.FindAll<Post>(p => p.Title = "Some Title");
Here's how i get a collection of "Reviews" (child of Post):
// var is strongly-typed to a "ICollection<Review>"
// "Rating" is a property on my "Review" POCO (derived from Post)
var reviews = repository.FindAll<Review>(r => r.Rating == 5.00);
The kicker is my repository is implemented with generics, and the type parameter ensures type-safety:
ICollection<T> FindAll<T>(Expression<Func<T,bool>> predicate) where T : Post
And it's implemented like this:
return myContext.Posts.OfType<T>.Where(predicate).ToList();
The OfType causes an inner join to the T (which is the child table), so only those records are returned.
Of course, i also have a service layer mediating between my UI and repository, but this should get you on the right track.
Also, you don't have to go with the whole Expression-predicate thing, i like this because it minimizes the number of methods on my interface, and gives full querying power to my controllers, whilst ensuring the queries are deferred to the point of the service layer, but not further.
If you don't like this, you could of course have regular parameters (string title, etc).
As i said, this architecture suited my domain requirements, so it may not necessarily suit yours, but hopefully it gives you some insight.
You can put a table in your EF model many times and just rename them to the entities you need. Just delete the columns you dont need from those.
For example, put in a Documents entity... now rename it to Invoice. Now add another one, and name it Quotation... on the Quotation, click on PayDate and hit the delete key. You can customize these all you want! You can do the same with other ORMs, just takes a little more work. With NHibernate you would manually create the Models, then map them to the same table, but only map what you need.

How to handle view model with multiple aggregate roots?

At the moment, i got quite badly fashioned view model.
Classes looks like this=>
public class AccountActionsForm
{
public Reader Reader { get; set; }
//something...
}
Problem is that Reader type comes from domain model (violation of SRP).
Basically, i'm looking for design tips (i.e. is it a good idea to split view model to inputs/outputs?) how to make my view model friction-less and developer friendly (i.e. - mapping should work automatically using controller base class)?
I'm aware of AutoMapper framework and i'm likely going to use it.
So, once more - what are common gotchas when trying to create proper view model? How to structure it? How mapping is done when there's a multiple domain object input necessary?
I'm confused about cases when view needs data from more than 1 aggregate root. I'm creating app which has entities like Library, Reader, BibliographicRecord etc.
In my case - at domain level, it makes no sense to group all those 3 types into LibraryReaderThatHasOrderedSomeBooks or whatnot, but view that should display list about ordered books for specific reader in specific library needs them all.
So - it seems fine to create view OrderedBooksList with OrderedBooksListModel view model underneath that holds LibraryOutput, ReaderOutput and BibliographicRecordOutput view models. Or even better - OrderedBooksListModel view model, that leverages flattening technique and has props like ReaderFirstName, LibraryName etc.
But that leads to mapping problems because there are more than one input.
It's not 1:1 relation anymore where i kick in one aggregate root only.
Does that mean my domain model is kind a wrong?
And what about view model fields that live purely on UI layer (i.e. enum that indicates checked tab)?
Is this what everyone does in such a cases?
FooBarViewData fbvd = new FooBarViewData();
fbvd.Foo = new Foo(){ A = "aaa"};
fbvd.Bar = new Bar(){ B = "bbb"};
return View(fbvd);
I'm not willing to do this=>
var fbvd = new FooBarViewData();
fbvd.FooOutput = _mapper.Map<Foo,FooOutput>(new Foo(){ A = "aaa"});
fbvd.BarOutput = _mapper.Map<Bar,BarOutput>(new Bar(){ B = "bbb"});
return View(fbvd);
Seems like a lot of writing. :)
Reading this at the moment. And this.
Ok. I thought about this issue a lot and yeah - adding another abstraction layer seems like a solution =>
So - in my mind this already works, now it's time for some toying.
ty Jimmy
It's tough to define all these, but here goes. We like to separate out what we call what the View sees from what the Controller builds. The View sees a flattened, brain-dead DTO-like object. We call this a View Model.
On the Controller side, we build up a rich graph of what's needed to build the View Model. This could be just a single aggregate root, or it could be a composition of several aggregate roots. All of these together combine into what we call the Presentation Model. Sometimes the Presentation Model is just our Persistence (Domain) Model, but sometimes it's a new object altogether. However, what we've found in practice is that if we need to build a composite Presentation Model, it tends to become a magnet for related behavior.
In your example, I'd create a ViewFooBarModel, and a ViewFooBarViewModel (or ViewFooBarModelDto). I can then talk about ViewFooBarModel in my controller, and then rely on mapping to flatten out what I need from this intermediate model with AutoMapper.
Here's one item that dawned on us after we had been struggling with alternatives for a long time: rendering data is different from receiving data.
We use ViewModels to render data, but it quickly turned out that when it came to receiving data through forms posting and similar, we couldn't really make our ViewModels fit the concept of ModelBinding. The main reason is that the round-trip to the browser often involves loss of data.
As an example, even though we use ViewModels, they are based on data from real Domain Objects, but they may not expose all data from a Domain Object. This means that we may not be able to immediately reconstruct an underlying Domain Object from the data posted by the browser.
Instead, we need to use mappers and repositories to retrieve full Domain Objects from the posted data.
Before we realized this, we struggled much with trying to implement custom ModelBinders that could reconstruct a full Domain Object or ViewModel from the posted data, but now we have separate PostModels that model how we receive data.
We use abstract mappers and services to map a PostModel to a Domain Object - and then perhaps back to a ViewModel, if necessary.
While it may not make sense to group unrelated Entities (or rather their Repositories) into a Domain Object or Service, it may make a lot of sense to group them in the Presentation layer.
Just as we build custom ViewModels that represents Domain data in a way particularly suited to a specific application, we also use custom Presentation layer services that combine things as needed. These services are a lot more ad-hoc because they only exist to support a given view.
Often, we will hide this service behind an interface so that the concrete implementation is free to use whichever unrelated injected Domain objects it needs to compose the desired result.

Resources