entity framework model first repository confusion - asp.net-mvc-3

I'm not sure if the repository patter is just the most common thing i'm seeing or if it is the best practices for abstracting a layer between the database and the controller. found some good resources today explaining persistence ignorance and why it's good for unit testing. However I still feel unclear on a proper entity framework implementation.
my current project, I went about creating the model first. i can safely say my aggregate roots are:
Business
User
Event
Invoice
these roots are fairly rich with references to "look-up entities" in the model. That is to say that my model contains 20 some odd entities, a number of which are used primarily for look-up purposes. If i were to implement the repository patter,
do i need to create a POCO for each entity?
Do i ever reference the auto-generated EF classes/entites as attributes of a repository?
Do i always need to use a repository when interacting with the entity framework?

Do i need to create a POCO for each entity?
You should have a plain old CLR object for most entities in your model. You should also have a POCO for each complex type (value object in ddd). Cases where you might not want a POCO for an entity is when creating gerund types for m..n relationships. You can create POCOs for these in EF 4.1, but you don't have to.
Do i ever reference the auto-generated EF classes/entites as attributes of a repository?
The only auto-generated EF classes/entities that I know of in EF 4.1 code first are the dynamic proxies that are created at runtime to populate your navigation and collection properties. You can't and shouldn't try to reference these in any of your source code. Oh, and I think you may be confusing the term "attribute". Attributes are special classes that you can use to decorate classes and methods. Entity classes cannot be used as attributes in this sense.
Do i always need to use a repository when interacting with the entity framework? No. In fact a lot of people say you shouldn't create a repository until you find that you need one. But if you drive your development from unit tests, you will find need for a repository interface quickly.

In Entity Framework, your DataContext class is a repository, and one over which you have a lot of control with EF 4.1. I don't in any way mean to sound flippant, because this is a really good question with a lot of bad answers.
When you use EF, you're already using the repository pattern. Take advantage of that and write less code. Resist the urge to over-architect.
1) This depends on how your behavioral model (your objects) translates to your data model (your database.) There is truly no prescriptive guidance.
2) EF already does this, if by attributes you mean properties.
3) You already do. :-)
Stephen

Related

External POCO classes to Aspnetboilerplate AbpEntities. i.e. no inheritace possible

We have a pretty common situation and I'd like to understand the best-practice or trade-offs in Aspnetboilerplate/AspNetZero.com to handle this best.
We import a package (NuGet) of pure C# classes (POCO). These are shared across several system. In our AspNetZero server, we want these to be first class persistent objects. However, they can't inherit from Entity, since they come from the Nuget. What is the best practice here?
My ideas to date (not being the expert here, of course):
If we were to use these classes as EF Navigation Properties in Apb Entities, i.e. always use them as complex-type properties of an Abp Entity class, it could do the trick. In this scenario, one would not even need to define a DbSet, although one could (see: https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application )
Alternatively, if we just reference these complex types from an Apb Entity, doesn't EF generate Entity-Proxies for these and automatically make them into EF Navigation Properties (see: https://blogs.msdn.microsoft.com/adonet/2009/12/22/poco-proxies-part-1/ ) or is this not an option the default Abp flow. We'd like to avoid too much custom code (risk).
Any other way via delegation?
Thanks for any Tips/Example/Info!

EF to ADO.NET transition

Need suggestion for migration few modules of asp.net mvc 3 application:
Right now we are using EF with POCO classes, but in the future for some performance driven modules we need to move to ADO.NET or some other ORM tool (may be DAPPER.NET).
The issue we are facing as of now is: our views dependent on Collection classes getting loaded through EF, what strategy should i used for these entity classes to be get loaded exactly the same way as by EF with some other ADO.NET or ORM tool.
What i want is to be able to switch between EF & ADO.NET with minimum of change at data access layer, as i don't want my Views to get effect by that.
You should use the Repository Design Pattern to hide the implementation of your data access layer. The Repository will return the same POCO's and have the same operations contracts no matter what data access layer you are using underneath the hood. Now this works fine if you are using real POCO's that do not have virtual methods for lazy loading in them. You will need to explicitly handle loading of dependent collections on entities to make this work.
What I've seen so far, a seamless transition from one ORM/DAL to another is an illusion. The repository pattern as suggested by Kevin is a great help, a prerequisite even (+1). But nonetheless, each ORM has a footprint in the domain layer. With EF you probably use virtual properties, maybe data annotations or, easily forgotten, a validation framework that easily fits in (and dismiss others that don't). You may rely on EF's ability to map across join tables. There may be things you don't (but would like to) do because of EF.
(Not to mention tools that execute scaffolding on top of an EF context. That would make the lock-in even tighter.)
Some things I might do in your situation (forgive me if I'm stating the obvious for you)
Use EF optimally. (Best mappings, best associations, ...) Preparing for the future is good, but it easily degenerates into the YAGNI pattern.
Become proficient in linq + EF: there are many ways to needlessly kill performance with EF. Suppose EF is good enough!
Keep looking for alternatives for high performance, like using stored procedures, parallellization, background processing, and/or reducing data volumes, and choose one when the requirements (functional and non-functional) are clear enough.
Maybe introduce an abstraction layer with DTO's that serve your views now, and in the future can be readily materialized by another ORM or ADO.
Expose POCO's as interfaces, which can be implemented by other objects later.
Just to add to both of these answers...
I always structure my solution into these basic projects:
Front end (usually asp.net MVC web app),
Services/Core with business processes,
Objects with application model POCOs and communication interfaces - referenced by all other projects so they serve as data interchange contracts and
Data that implements repositories that return POCO instances from Objects
Front end references Objects and Services/Core
Services Core references Objects and Data
Data references Objects
Objects doesn't reference any of the others, because they're the domain application model
If front end needs any additional POCOs I create those in the front end as view models and are only seen to that project (ie. registration process usually uses a separate type with more (and different) properties than Objects.User entity (POCO). No need to put these kind of types in Objects.
The same goes with data-only types. If additional properties are required, these classes usually inherit from the same Objects class and add additional properties and methods like generic ToPoco() method that knows exactly how to map from data type to application mode class.
Changing DAL
So whenever I need to change (which is as #GetArnold pointed out) my data access code I only have to provide a different Data project that uses different library/framework. All additional data-specific types etc. are then part of it as well... But all communication with other layers stays the same.
Instead of creating a new Data project you can also change existing one, by changing repository code and use a different DAL in them.

Basic Entity Framework Questions

I have an existing database, which I have been happily accessing using LINQtoSQL. Armed with Sanderson's MVC3 book I thought I'd have a crack at EF4.3, but am really fighting to get even basic functionality working.
Working with SQL 2008, VS2010, the folder architecture appears to be:
ABC.Domain.Abstract
ABC.Domain.Concrete
ABC.Domain.Concrete.ORM
ABC.Domain.Entities
Per examples, repository interfaces are abstract, actual repositories are concrete. Creating EDMX from the existing database puts that in the ORM folder and the Entities holds the classes I designed as part of the domain. So far so good.
However! I have not once persuaded the deceptively simple EfDbContext : DbContext class, with method to work...
public DbSet<ABC.Domain.Entities.Person> Person { get { return _context.Persons; }}
It complains about missing keys, that Person is not a entity class, that it cannot find the conceptual model, and so on.
Considering I have a basic connectionstring in the web.config, why is not creating a model on the fly to do simple matching?
Should the ORM folder exist, or should it simply be Concrete? (I have a .SQL subfolder for LINQtoSQL concret so it suits me to have .ORM but if it's a flaw, let's fix it).
Should I have my homespun entities AND the automatically produced ones or just one set?
The automatic ones inherit from EntityObject, mine are just POCO or POCO with complexTypes, but do not inherit from anything.
What ties the home designed Domain.Entities.Person type to the Persons property of the Context?
Sanderson's book implies that the matching is implicit if properties are identical, which they are, but that does not do it.
The app.config has an EF flavoured connection string in it, the web.config has a normal connection string in it. Which should I be using - assuming web.config at the moment - so do I delete app.config?
Your help is appreciated. Long time spent, no progress for some days now.
What ties the home designed Domain.Entities.Person type to the Persons
property of the Context?
You seem to have a misunderstanding here. Your domain entities are the entities for the database. There aren't two sets. If you actually want to have two sets of object classes (for whatever reason) you must write any mapping between the two manually. EF only knows about the classes which are part of the entity model.
You should also - if you are using EF 4.3 - apply the DbContext Generator T4 template to the EDMX file. Do not work with EntityObject derived entities! It is not supported with DbContext. The generator will build a set of POCO classes and prepare a derived DbContext. This set of POCO classes are the entities the DbContext will only know about and they should be your only set of domain entities.
The created DbContext will contain simple DbSet properties with automatic getters and setters...
public DbSet<Person> People { get; set; }
...and the Person class will be created as POCO as well.
Download the entity framework power tools:
http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d
Right click in your project to 'reverse engineer an existing database' it will create the code classes for you. No need to use EDMX ,and this method will create the DbContext derived class for you
There are many questions here and you won't get an answer, but I'll stick my 5 pence for what it's worth.
Sanderson's MVC3 book
Your problems are not to do with MVC3, they are to do with Entity Framework and data persistence layer.
ABC.Domain.Abstract ABC.Domain.Concrete ABC.Domain.Concrete.ORM
ABC.Domain.Entities
Can you say why this is separated in such a way? I would argue and say that ABC.Domain should contain your POCOs independent of your persistence layer (EF) and your presentation layer (MVC). Your list implies that your domain contains ORM and your data access entities. I'm not arguing here, what I'm trying to say, is that you need to understand what you really need.
At the end of a day, I'm certain that a simple example would suffice with ABC.DataAccess, ABC.Domain and ABC.Site.
Do you understand why repositories are abstract and concrete? If you don't, then leave out interfaces and see whether you can improve it with interfaces later.
Person is not a entity class, that it cannot find the conceptual
model, and so on.
Now, there are multiple ways you can get EF to persist data for you. You can use code first, where, as the name implies, you will write code first, and EF will generate database, relations and all the relevant constraints for you.
You can use database first, where EF will generate relevant class and data access related objects from your database. This is less preferable method for me, as it relies heavily upon your database structure.
You can use model first, where you will design your class in EDMX designer and it will then generate relevant SQL for you.
All of these might sound like a bit of black box, but for what you are trying to achieve all of them will work. EDMX is a good way to learn and there are many step by step tutorials on ASP.Net.
but if it's a flaw, let's fix it).
You will have to fix and refactor yourself, there is no other way to improve in my honest opinion. I can give you a different folder/namespace structure, but there will always be a "better" one.
Should I have my homespun entities AND the automatically produced ones
or just one set?
Now this depends on the model that you have chosen. Database first, code first, code only and whatever else is there. If you are following domain driven development, then you will have to work with classes, that represent your business logic and that are not tied up to your data persistence layer or presentation layers, therefore POCO is a way forward.
What ties the home designed Domain.Entities.Person type to the Persons
Now this again depends on the model that you are using.
The app.config and web.config
When you are running your web application, the connection string from web application will be used. Please correct me if I'm wrong.
Your help is appreciated. Long time spent, no progress for some days
now.
General advise, leave MVC alone for the time being. Get it to work in a console application and make sure you feel comfortable with options offered in EF. Good luck :)
The solution to why nothing worked code-first...
...turned out to be a reference to System.Data.EntityClient in the connection string, which ought to have read System.Data.SqlClient.
Without this provider entry being correct, it was unable to work code-first.
Finding which connectionString it was using was a case of deliberately mis-spelling a keyword in the connections there were to choose from - they all were named correctly - but were in app.config, and 2 places in the web.config. With a distinct naming error, when the application threw an error trying to create the domain model, it was easy to identify which connection string my derived DbContext class was using. Correcting the ProviderName made all the difference.
Code-first is now working just fine, with seeded values on model changes.

Can I define one repository class for all the entity classes which I have

I am working on an MVC 3 web application which contains around 15 entity model classes representing 15 DB tables, I am currently performing all the business logic in one model repository class which is called from all the controller classes I have. I am doing all my work in one repository to:-
avoid partial updates.
wrap all the modification (insert, update, delete) into one DB transaction.
to avoid defining repository class for each model object and creating UnitOFWork class to coordinate between all the repositories, which I find that it will complicate the code and add extra effort.
so will my approach of having one repository class suffer from problems such as performance, security, etc, or other problems that I should be aware of.
You can do this if you want. However you might end up with an unwieldy repository implementation. You say you want to avoid defining one repos class for each model object. That is another extreme I would not recommend. There is usually a better middle ground.
There is a book out there called Domain Driven Design. One of its recommendations is to try using "Aggregate Root" repositories. This is where you organize your entities into groups according to their relationships, and then create one repository for each group. The main entity in the repository is referred to as the "aggregate root" of the group, and has other entities "dangling off" of it.
For example, say you have an Order entity that has a collection of LineItem entities. You can really only access the line items through the order, so you don't need a separate LineItemRepository. You can query the Order, and eager or lazy load the line items. The Order may then have a navigation property to a CustomerAccount entity, which has a collection of PaymentProfile entities. Again, same pattern -- you just create a repos for the customer account, and never query for the PaymentProfile directly. Query for it through the CustomerAccount.
Also I know from one of your previous questions that you are using EF. EF manages transactions for you. Each time you call SaveChanges, EF will run it in a transaction. So #2 is not really a good reason to have 1 giant repository.
Update
As far as UnitOfWork, with good upfront design, you can manage UoW across repositories pretty easily. Each of our repositories has a UnitOfWork object (which basically wraps EF DbContext). None of our code constructs the object directly. Instead we use our Dependency Injection / Inversion of Control container (Microsoft Unity) to automatically construct a UoW each time a repository is constructed by a controller (again, using dependency injection).
By configuring the dependency lifetime to be one instance for each request we can be sure that, at least in our MVC project, each repository gets the same UoW instance (and therefore all repositories have the same DbContext instance).
<register type="IUnitOfWork" mapTo="CustomDbContext">
<lifetime type="singleton-per-http-context" />
</register>
Why not implement generic repository. Check out this article, hope it can be of some help
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

If Entity Framework is meant to work with POCOs, then why the dependency on IObjectSet?

I keep hearing about EF 4.0, POCO, IObjectSet, UnitOfWork (by the way, UoW is atleast more than 17 years old when I first heard it) etc.
So some folks talk about Repository "pattern". etc. There are numerous bloggers showcasing their concoction of a "wrapper" or repository or something similar.
But they all require IObjectSets (or in some cases - IQueryables) to be hanging off their POCOs. Expectation seems to be that you can write queries against them.
So if one needs IObjectSet and not just IList or some other simpler collection, why are we saying this is POCO and free from EF?
If I want to swap EF from underneath, I need to make sure my "other" O/R Mapper (I know I know.. EF is not just an O/R Mapper) understands IObjectSet and be able to parse the ExpressionTrees from the queries, execute and otherwise behave similar to EF.
IObjectSet is not the interface that makes an Entity POCO, it's just the persistence container IObjectSet. The point of POCO is to prevent you from having to derive your Model classes from an EF type, which the T4 POCO template in EF4 provides.
The Repository pattern is an optional additional layer of abstraction from your ORM to allow easier implementation of a different one if the need arose. Separation of concerns etc etc.
Take a look at Entity Framework Code First: http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx
In response to the phrase: "If I want to swap EF from underneath":
In my business, it is more likely that I would swap out the database, say from Oracle to SQL Server (or vice versa), than that I would swap out the data access framework. On the other hand, there do exist options that make EF a favorable choice.
There are other LINQ providers than those provided by EF (e.g. LLBLGen). Sure, swapping out an EF data tier for NHibernate or EasyObjects would be difficult, because the frameworks do not have sufficient feature parity to ease the transition; however, LINQ was designed to open the way for other LINQ providers to step in and provide their own solution.
Your question contains a wrong statement: Correct is that POCOs do not depend on IObjectSet.
POCOs themselves are independent from EF. Or better: They are supposed to be independent from EF. Since YOU are implementing the POCO classes you are finally responsible to make this sure. (Otherwise the term POCO would be the wrong one.)
If you are using the standard T4 template to create POCO classes from a model description instead of writing the classes on your own the template ensures that the classes do not depend on EF - they are not derived from Entity and collections as members of a class are generated with ICollection by this template, not with IObjectSet.
Repository pattern is another question. The POCO T4 template does not create a Repository as an abstract interface to act on a database with POCOs. It creates a derived ObjectContext which is rather an EF specific implementation of a possible repository interface (or at least helps to easily implement a possible repository interface).
If you want to have a repository interface which doesn't depend on EF or LINQ you have to define it this way. Nothing forces you to use IObjectSet or IQueryable in that interface. Perhaps the examples of implementing the Repository pattern you saw didn't intend to be independent from Entity Framework or LINQ.
An example:
Suppose, in your business layer you need a list of all products of a given category returned from the persistance layer. What would this layer expose to fulfill the request?
If you only have databases in mind which offer a LINQ provider you might design the repository interface like so:
public interface IProductsRepository
{
IQueryable<Product> AllProducts { get; } // Product is the POCO class
}
A concrete implementation of this repository based on EF would simply return an ObjectSet<Product> from the ObjectContext which the T4 template did create.
And your business layer runs a query this way:
IProductsRepository rep = new SomeConcreteImplementationOfProductsRepository();
IList productsOfCategory =
rep.AllProducts.Select(p => p.Category == "stuff").ToList();
But if you want to be more open what kind of persistance storage you like to support it might be better to design the repository independent from IQueryable. The consequence could be that your abstract repository interface needs more specific methods to answer requests from the business layer, for instance you need now:
public interface IProductsRepository
{
IList<Product> GetProductsOfCategory(string category);
}
and the business layer does this:
IProductsRepository rep = new SomeConcreteImplementationOfProductsRepository();
IList productsOfCategory = rep.GetProductsOfCategory("stuff");
A concrete implementation of this Repository using EF (or another data framework supporting LINQ) could still leverage a LINQ query like the business layer did in the first example. But other implementations could work in another way (say: you have a "database" which stores products in one text file per category. Then the implementation for that interface method would read one specific file from disk. Or your repository implementation asks a webservice for the data, and so on...)
Key point is: If you are using POCO classes you are open for all those kinds of repositories. EF with POCO support doesn't force you to build repository interfaces based on IQueryable or even IObjectSet. It finally depends on what kind of persistance layers you have in mind. The more different they are the more specific methods you might need to support in your repository interface and the more work you'll have to implement those methods. Using IQueryable is a comfortable compromise which allows to define a simple repository interface while enabling simple implementations by EF but also other databases with LINQ provider. I think that's the only reason why you see examples of repository pattern implementations with IQueryable so often. It's not an inherent restriction imposed by EF with POCOs.
(That's how I think about it, not being an expert in design patterns, so heavy attacks and corrections in the comments are welcome.)

Resources