I haven't actually used it, yet, because I am just starting on the DAL, but I have made some changes. I took out EntityObject in the template and replaced it with class for POCOs. I also added the method below, and it's using statements, to the template.
public virtual IEnumerable<E> Find(Expression<Func<E, bool>> filter) { return objectSet.Where(filter); }
Hello,
You're using a collection to return a list and cast it to IQueryable the problem with this is that a different LINQ provider is used under the hood "LINQ-to-Objects" rather than "LINQ-to-Entities" which might causes your tests to fail in production.
This kind of code belong to the data layer of the application and as such should be tested using Integration Tests and not really Unit Tests, it's misconception that you should unit test everything.
Unit Tests are one of few approaches to test your code, not the only choice and in this case in my opinion and the general opinion of most it is wrong.
I'd be glad to hear your opinion about it. :)
Nowhere is anything being returned as a list. The collection you are referring to is System.Data.Objects.ObjectSet, which directly implements the IQueryable interface.
Also, LINQ-to-Objects is not used. LINQ-to-Entities is definitely used, otherwise you would not be able to generate the SQL queries dynamically. You can test this with the following code.
var unitOfWork = new NorthwindUnitOfWork(new NorthwindEntities());
var query = from c in unitOfWork.CategoryRepository.All()
where c.Category_Name.StartsWith("A")
select c;
string sql = ((ObjectQuery)query).ToTraceString();
Console.WriteLine("sql:\n\n{0}", sql);
Console.ReadKey();
This is the output that is generated from the above code.
sql:
SELECT
[Extent1].[Category ID] AS [Category ID],
[Extent1].[Category Name] AS [Category Name],
[Extent1].[Description] AS [Description],
[Extent1].[Picture] AS [Picture]
FROM [Categories] AS [Extent1]
WHERE (CHARINDEX(N'A', [Extent1].[Category Name])) = 1
This repository and unit of work is very similar to what was written by Tom Dykstra (a Senior Programming Writer on Microsoft's Web Platform & Tools Content Team) at: 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
The main difference between this and microsoft's code is their article was written for a different version of entity framework.
Ok, it took me a few minutes to realize you were talking about the MemoryRepository.
So yes, you are correct. It's possible to write unit tests using the MemoryRepository that will fail because you are using a feature that is not supported by LINQ-to-Entities.
an example of this would be...
//passes when using the MemoryRepository, but fails when using the EntityRepository.
var q = from o in collection
where MyFunction(o) == true
select o;
Obviously this works because in your example you use the actual implementation whereas I'm speaking about your Unit Tests where you use MemoryRepository to mock out a repository.
Your MemoryRepository is implemented using a list, the methods that returns IQueryable are using the LINQ-to-Objects provider not LINQ-to-Entities.
This might cause some of your Unit Test to pass while failing in production.
I setup my projects using ado.net entities, which is accessed via repositories and a unit of work. typically, i'll encapsulate those with a facade or service, which is used by my controllers.
i've been using this to unit test my facade's and services.
how are you setting up your architecture?
Sorry for the late reply, well, up until today I mostly used this approach but I'm moving toward a different one and checking the Front Controller and the Command pattern which adheres more to the SoC principle.
You can read it up here http://martinfowler.com/eaaCatalog/frontController.html
I'll elaborate a bit.
Instead of handing the repository to the service and then to the controller, each command that handles the request takes a repository or few, the front controller uses the strategy pattern to invoke the commands accordingly to the incoming request.
The problem with this approach is that you need to think carefully up-front about the commands, because you never want so many of them. ;)
Hmm. have never used those patterns before. Though our use of activities sounds a lot like the command pattern. I tried experimenting with a DCI pattern before, but ended up going back to the repository / facade way of doing things. I'll have to read up on the front controller, I'm not familiar with that at all. you have a blog or any examples?
Well, I didn't write about it but throughout my research for a project I'm working on I found this example at codeplex http://silk.codeplex.com/ there they call it handlers.
You can find my blog at http://shilony.net ;)
Hi,
I'm using EntityFramework 4.3
I tried your template and it generated the following error:
cannot convert from 'EntitiesModelContainer' to 'System.Data.Objects.ObjectContext'
in generated file: ####UnitOfWork
The template is not compatible with that version of entity framework. The base objects in EF were changed. This template works with the EF included with VS2010.
I'll have to rewrite the template for different versions of EF.