You might have been aware that MS just released Entity Framework 4 CTP5 some days ago. There have been some comments asking me when the data access layer would be upgraded to that version. Since I had been quite busy these days, the answers for these questions was just a promise that I would do the upgrade when I had time after I finished investigating the new release carefully. However, some readers seem to be anxious waiting for the code updated so they keep asking me for the progress (and I feel good because I know there are some ones who are interested in the framework I built :)).

– We do not need to register entity any more, just add mapping class(es) to the ModelBuilder then we are all set. Well, this is for your information only, since this framework will do this automatically in the XContextBuilder class.

– The most and important thing, I think, is EF now will automatically map entity relationships without explicitly writing the mapping code. For example:

I have an entity Customer that has many Orders. These two classes will be defined as below:

The one thing I don’t get is passing the mappingAssemblies manually. There’s got be a better way to scan (reflection or IoC) and find assemblies containing EntityTypeConfiguration and just load them in automatically. Thoughts?

I got you. A follow-up to that is On BeginRequest, you actually pass in the assembly name via the .Init method. Besides an IoC, shouldn’t that be done on start-up and not on every request? I see you initialize the context once but it’s unintuitive to me to pass a mapping assembly in BeginRequest instead of start-up. Can you elaborate?

Initializing the ObjectContext in BeginRequest and close it on EndRequest is an approach to manage ObjectContext life-cycle which is specific to Web application. You can refer to “Open Session In View” approach (from Java community): http://community.jboss.org/wiki/OpenSessioninView to get understanding on why we do not initialize ObjectContext on start up but every request.

I think you cannot do that without changing the code. For instance, the GetByKey(id) method on the Repository uses the hard-coded entity key as “Id”. So I think when you are not using Id for the key, you have to change the implementation.

I just do the mapping at the concrete class level. For example, with a base User and Employee/Patient, use Haskey at Employee and Patient class. It works for simple update, haven’t try on complicated graph with multiple change/insert/delete, etc.

BTW, find out lots of good stuff you put in there. For example, didn’t realize the Update in GenericRepository actually does several things I was struggling to do manually. It’s really great. Thanks.

Using this framework, how would you be able to utilize the Seed method. I need to seed static values into a table. Usually that’s done overriding the DbContext Seed method or the Initializer’s Seed method. Any idea?

FYI. I added some test classes under Lab folder of the Infrastructure.Tests assembly to demonstrate almost all of above steps, except the code to store and manage the MyDbContext. Please check out the code at http://code.google.com/p/ef4prs/source/checkout and try it.

Thanks huyrua. IMHO, I think you should support it via ObjectContextBuilder. You have ObjectContext there, so you can allow another method that would be called to seed something based on specific TEntity. You can then call ObjectContext.SaveChanges() after seeding is done. I don’t know enought about he ObjectContext but I see it has methods to retrieve an entity and save and that’s all we need. Thoughts?

Why wouldn’t we create a class that wraps the DbContext to seed the data at application startup, just right after the DbContext being initialized? Below code demonstrates how to initialize DbContext and also seeds the initial data in ASP.NET MVC application

Happy holidays! Question for you: when attempting to use the set of Get methods with paging support (i.e. which use ‘skip’ and ‘take’ parameters), the LINQ-to-EF dies with this exception (to paraphrase): “can only use skip and take on a sorted collection; please use orderby before skip and take”.

Since this a fully generic repository, it’s not possible to specify a “strongly-typed” OrderBy (e.g. “x => x.Name”), so my solution thus far was to use the System.Linq.Dynamic library and change the fundamental GetQuery to be:

Thus, if the “sortParameter” is not specified, it will fall back to a default sort of “it.Id” (by ID); but otherwise, you can specify any other property of the current object to sort by. Adding the sort here satisfies the L2E skip and take requirements further “downstream” – the exception is gone, and I am able to use “true” paging where required.

Opinions on this approach? Is there a better way?

Allen

P.S. Following along, I am also able to add overloads of the paged Get methods which return the total count of records as an out parameter, by using your built-in Count methods:

So, regarding the bug of the Get methods with paging parameters, I will remove them out of the Repository to eliminate the errors that may happen. The reason is I don’t really like the magic string for sortParameter which is error prone IMHO. I hope you feel comfortable with this. Otherwise, you can absolutely change or add more overload methods to perform ordering like the idea you proposed 🙂

In conjunction with keeping some overloads to fall back on the “default sort”, now we can have the option to keep the API surface as clean as it was in Huy’s original implementation, and yet now have the ability to pass in a strongly-typed orderby as necessary anytime.

Huy, also, if you make the “queryOrder” parameter (enumeration) optional, defaulting to QueryOrder.Ascending (or descending), the method signature will become one parameter cleaner and still retain all this new functionality.

Thanks. I just learned that you can not control lazy loading on scalar fields. So if I load message object, message body always get loaded? I tried returning IQueryable, which allows you to control which fields to load. But it doesn’t work if the class contains other complex objects, because those objects are not loaded with IQuerayble, and throw an error when you try to reference to fields inside the other objects.

This is really really bad. I have been trying hard to convince our management and DBAs that EF is more efficient and productive. But now I start doubting myself.

If you have time, you could verify whether or not EF will issue an SQL to select only Name field in the Person table. If it doesn’t, feel free to add an overload method in the IRepository to support executing Stored query.

If repository returns IQueryable, you can control which field get loaded and it does generates the right select in SQL. The problem is any computed field, as simple as get {return “test”;}, will not work.

You got “The specified type member ‘ComputedFieldName’ is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.”

If you happen to know the solution and be a dedicated workaholic, let me know. Otherwise, happy new year ^_^

I’m wondering if this framework can be used on WPF application, Specifically if the ObjectContext will better created once per application (and where is the best place to initialize it) using the ObjectContextManager or once every time the Business Object need it using the ObjectContextBuilder.

Also is there a way to run Unit Test against the framework without persisting to the data base?

Quick question, how would I go about changing the database column name of the Id in my mapping class in CTP5? I used to be able to do it with MapSingleType but that doesn’t exist anymore. ‘Property’ has a HasColumnName that allows me to specify what the database column name is, but I don’t see a mechanism for it for the identity (‘HasKey’).

Thank you for sharing the great library. I have a question around the Unit of Work (UoW) pattern that you put together.

UoW is tied to a Repository and I am wondering how can it work across repositories. Can the UoW implementation be a singleton to address this issue. And also for the two-phase commit across the databases (with different dbContexts) can the UoW use TransactionScope instead of the Transaction as I believe TransactionScope works like a regular Transaction (with out DTC) for dbcontexts with the same connection string.

If I am working with multiple databases via different DbContext, the TransactionScope should be used to commit the transactions. That said, each call to XRepository.UnitOfWork.SaveChanges() will not make any change to a database until the TransactionScope is committed.

When do you call UnitOfWork.BeginTransaction() explicitly vs just UnitOfWork.SaveChanges()? I ask this because I’m trying to integrate some code from another NHibernate based framework. It has a global TransactionManger that has
public TResult ExecuteCommand(Func command)

It executes all requests by calling begin and commit transaction, and also add business warnings and catch business exceptions, then add it to the dto response. It’s a neat way to handle exception and warnings at service layer.

I’m not sure if I fully understand either framework and wonder if this global TransactionManager compliment your objectcontext management code, or you already have this just that I didn’t get it.

UnitOfWork.SaveChange() implicitly commits the transaction with IsolationLevel is ReadCommitted. This is the default implementation of underlying ObjectContext and/or DbContext.

When you want to start a transaction with the IsolationLevel other than ReadCommitted, you should call UnitOfWork.BeginTransaction([IsolationLevel]) then UnitOfwork.CommitTransaction() or UnitOfWork.RollBackTransation().

How can I detach an entity to work with it in another context? I have already added the detach method to IRpository but I’m still stuck since it doesn’t seem to be detached. Should I detach child objects as well? (E.G. I have album entity which has a navigationproperty to AlbumImages. Should I detach album Images one-by-one too?)
Is there any generic way to do this?
Thanks.

One more thing I’d like to note:
If we want to use this framework in a web application, with WebContextManager, we should add:
private WebObjectContextStorage _storage;
ObjectContextInitializer.Instance().InitializeObjectContextOnce(() =>
{
ObjectContextManager.InitStorage(_storage);
ObjectContextManager.Init(new[] { Server.MapPath(“~/bin/mapping-assembly.dll”) });
});
}
Which means adding a reference to DAL (Infrastructure.Data.EntityFramework) to the UI which is something I’d like to avoid.
is there any other way to initialize ObjectContext? (e.g. in BLL maybe?)

A possible solution I thinh you can consider is implementing a BootStrapper class which does all the initialization for ObjectContext/DbContext (and something such as IoC container). This class will then be called in the Global application.

The data annotation is the new feature since the CTP5 release and it is not incorporated to this framework yet, I also dont have plan to apply this but some initial thoughts of mine is that you might not need to use the mapping classes if you are applying data annotation for entities. There might be more or less works to do with this but… please bear with me that at the moment I dont have time to think deeply about this until the final release of EF.

If SqlFieldDataTypeSqlOperator contains only the keys of the other table (a many to many relationship) then you don’t need to create a mapping class SqlFieldDataTypeSqlOperatorMapping. Please take a look at the demo mappings for Product and Category in the source code.

I have two suggestions for improving/removing bugs.
In GenericRepository.cs, instead of hard coding ObjectContext in GetEntityName, we can do:
private string GetEntityName() where TEntity : class
{
return string.Format(“{0}.{1}”, ObjectContext.DefaultContainerName,_pluralizer.Pluralize(typeof(TEntity).Name));
}

Also, GetByKey method only works for entities with primary fields named Id. We can add a method to extract the key property name and then, create the new entity key:
private EntityKey GetEntityKey(object keyValue) where TEntity : class
{
var entitySetName = GetEntityName();
var objectSet = ObjectContext.CreateObjectSet();
var keyPropertyName = objectSet.EntitySet.ElementType.KeyMembers[0].ToString();
var entityKey = new EntityKey(entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) });
return entityKey;
}
Then we can call this method from GetByKey method like:
EntityKey key = new EntityKey(fqen, ENTITY_KEY_NAME, keyValue);
I have tested this a it worked ok. But I’m not sure if I am missing something. What do you think huyrua?

I’m thinking about using NBuilder to create some in-memory data for unit testing. I have some business logic in the entities and some query logic in the customRepository. Service layer calls customRepositories, but for simple ones, they also go directly against generic repository.

Where does NBuilder fit into this picture? Especially for testing the query logic.

NBuilder basically takes any entity class and builds test data using fluent syntax, very convenient for creating all kinds of unit test scenarios. I guess the real question I was trying to ask is how to test the repository. Most online articles suggest creating a fake repository or mock, but none of those test the real thing.

In my case, there are lots of query logic using custom or generic repository (getting user list but exclude some based where they sit) and many calculated properties in the entity (displayname based on real name, nickname and bunch of other things, etc).

I can test entity level rules by creating a list using NBuilder. But how can I test the repository queries without creating a FakeCustomerRepository, and without relying on a live database through EF? Speed is one thing, our data also come from bunch of other systems on demand, making it impossible to auto test live.

I’m trying to figure out where do I plug-in the in-memory test data for repository test. Is there an easy way to swap out EF GenericRepository implementation and fill the data there (Infrastructure.Data.InMemory)? Or do I have to make all the queries using specification pattern so I can test queries independent of repository?

– If I am testing business/service layer, the repository should be mocked. In this case, a ‘FakeRepository’ should be employed that returns hard-coded data as a result of query operations,… This is so-called ‘test isolation’. Note that I don’t have to explicitly implement a FakeRepository class, instead, I use a mocking framework like Rhino Mock to create an instance of IRepository.

– If I am testing the data access layer, e.g. repository classes, then IMHO, I have to open the real database connection as well as apply ‘roll back’ pattern to keep the data unchanged when each test is executed. And yes, it slows the test because of database operations, but I think it is a must to make sure the repository should work as expected against a production database.

Thanks for the update. Those are the solutions I have been reading about. But sometime it’s hard to separate business logic from the repository. For example, I get a list of test result back, but need to filter down based on certain keywords, user group, department and location without bring them all in first, so the query stay with repository. The repository, query and EF stuff can be tested against live database as integration test. However, automated unit tests are almost impossible, some test cases aren’t even exist in live database.

I tried to move most queries into specification, then use NBuilder to build collection AsQueryable and feed it to SatisfyingEntityFrom … similar to what you have in Find(Specification), which the service layer calls. This allows query to be tested separately and also works correctly against real database.

But I’m not really sure if I’m heading for the right direction. Also trying to figure out how to make more complicated specifications beyond x.Name==”whoever”, like join,group,max, etc. using expression. Looks like it should be possible.

Just realized that all queries are written in LINQ, so in theory it shouldn’t matter what the data sources are. Somewhere in the framework, you should be able to intercept and plug in a collection generated data that feed into the repository and test the query logic, right? Any hint where? Thanks.

I have also tried the same with specification, like
Find(NewlySubscribedSpec().And(InZipCodeSpec)...

But often queries do not feel natural as specification (I have read queries are NOT spec and should be treated differently). Besides, it’s also much easier to throw in some stored procedure calls when using extensions. Testing query logic (not the EF part) is also very intuitive.

There is nothing wrong with extension method you explained, IMO. They are methods for querying specific piece of data out of this generic framework.

The point here is, I think, it shouldn’t be put in the infrastructure but somewhere else, e.g. business layer or a satellite .NET assembly which is specific for a particular business domain. The same thoughts for specifications.

Thanks for the update. Yes, all the query logic and extensions are in business layer, next to repository and called from service layer. After a few tries, I like specification better than extension after all.

Some of our queries are like FindTopCustomerInEachCategory, which is more likely done in a stored procedure for performance reason. I was wondering if it’s possible to embed a stored procedure inside a specification, so you can find new star customers with something like
Find(TopCustomerInEachCategorySpec(10).And(NewlySubscribedSpec(30))

From a specification, it’s impossible to execute a stored procedure from IQueryable instance because it only ‘sees’ an IQueryable. Although you can do that from the ObjectContext with the methods like CreateStoreCommand or ExecuteStoreQuery, etc. but you might need to extend the repository (or subclass it) to expose these methods to the caller.

Hi huyrua,
I stumbled upon your blog and I find it very useful in my experimentation. I hope you don’t mind me borrowing your work. Anyhow, I can’t get off of this mapping error that says

SetUp : System.InvalidOperationException : The configured property ‘CompanyAddress’ is not a declared property on the entity ‘Company’. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.

The error only occurred after I change Address CompanyAddress to IAddress CompanyAddress.

Also, you can see in my code how I create my foreign key relationship which I think little bit ugly. The reason is that, I’d like to control how the field name will reflect in my database. I hope there is a neater way to do this probably in mapping class.

I think the exception is obvious that you cannot use the interface but a primitive type OR a concrete entity, e.g. CompanyAddress. I am not sure if there is a way to map the relationship between an entity with an interface (like Company and IAddress in you case) but currently the framework does not seem to support that way of mapping.

Yeah, just found it out just now. I get away of the error and by removing data annotations but as you said it seems like ef ctp5 does not support mapping entities with interface. Too bad! This would seemingly affect my whole design.

u making upgrade to EF4.1. Haven’t actually red are there any major changes compared to ctp5 and one could probably do the upgrade himself but it would be nice to have your official version with maybe some improvements mentioned by other users here.

anyway really good job dude, i actually made some nice money on a project using your repository pattern implementation.

It’s good to know you find the framework helpful and also made some money frome it 🙂

I know that there is no official realease which incorporate changes from people’s comment up till now. But since there will be an official release of EF by this month as announed from Microsoft, lease wait until that time.

Well the Release Candidate of EF4.1 is allready out (just in case u haven’t maybe noticed) for 2 days now and they said there will be no changes from on framework level (just evaluating and fixing eventual bugs reported by users) before the final release which is due in less than a month.
But as you said maybe it’s better to wait till the real stuff comes out, just to be sure.

First of all, I love your work here. I have been looking for a solid EF 4 repository pattern for almost 2 weeks now and yours blows everything else away. So thanks for sharing and great job.

I have adapted your pattern slightly (really just going backwards) to take out the specification (at least for now i’m happy with just linq) and the objectcontextbuilder/manager. Also I am using EF 4.0 only, not CTP5 (or now 4.1). This is simply because I need to have an architecture that is ready to ship to production in a few months and I’d rather rely on a more tried solution of a physical edmx and T4 POCO instead of code first.

Anyhow, my question is, why are you using CreateQuery() instead of CreateObjectset() in your GenericRepository class? Wouldn’t it be more straightforward, and also you wouldn’t need to resolve the entity/container names?

Regarding the question, I thought each method has its own purpose, e.g. in the GetQuery() method I call ObjectContext.CreateQuery[TEntity](entityName) which returns exactly the desired IQueryable. But I haven’t acknowledged about the CreateObjectSet can be use in place of CreateQuery that somehow more convenient and shorter way to gain the same result. So you can use CreateObjectSet in stead of CreateQuery as long as you find it relevant.

Okay, that’s what I figured but just wanted to make sure I wasn’t missing something about CreateObjectSet() that would cause me not to want to use it.

Another question, I am having a difficult time wrapping my head around how I would use ObjectContextStorage in a WCF environment.

So basically my architecture is ASP.Net webform (service factory pattern for client proxy) -> WCF service -> Your Repository pattern -> EF 4 (with POCO T4) It seems like in this case, it doesn’t make sense to store the context, because it only is needed on demand upon activation of the WCF service. So basically I am creating and disposing the context in every WCF method. Is there a better way to do it? Like some sort of storage specifically for WCF service? If so, how would it perform in high volume transactional scenarios?

In the context of Wcf, you may want to implement a WcfObjectContextStorage (or WcfDbContextStorage if you’re working with DbContext)

In order to implement WcfXXXStorage, Sharp Architecture is a good source of reference because the idea to implement WebObjectContextStorage/WebDbContextStorage or SimpileObjectContextStorage/SimpleDbContextStorage in this framework is mostly inspired from it.

In short, you can refer to Sharp Architecture and look for the WcfSessionStorare (SharpArchitecture uses NHibernate), but once you get the idea, you can implement it for ObjectContext/DbContext.

I have enjoy learning using you code sample. I have a quick question on writing inner joins. can you give a sample of using GetQuery().Where(x => x.Id == Id) and joining with about Object? Or is there a better way of doing it. I was thinking maybe query the first object then join to second one.

I have situations where I need to insert data across several repositories and would like to save all the changes in one shot.
With this implementation, I have to call:
MyRepository1.UnitOfWork.SaveChanges();
MyRepository2.UnitOfWork.SaveChanges();
MyRepository3.UnitOfWork.SaveChanges();

How would you implement eager loading Huyrua?
One approach would be to derive a new repository class(e.g. CustomerRepository) and add the method:
public Customer GetCustomerWithProduct(int customerID)
{
GetQuery(x=>x.Id == customerID).Include(c => c.Products).ToList()
}
Is there any other approach?
P.S. Any ETA on upgrading to EF 4.1?
Thanks.