December 2013
Volume 28 Number 12
Entity Framework - Entity Framework 6: The Ninja Edition
By Julie Lerman | December 2013
With the latest major release of Entity Framework, EF6, the Microsoft object-relational mapping (ORM) tool has reached new heights of “ninja-ness.” It’s no longer the country cousin to long-established .NET ORM tools. EF is all grown up, and it’s winning over former die-hards.
Entity Framework has evolved through the choppy waters of its infancy, where it began as a tool focused on database developers—and inspired the wrath of agile developers within the .NET community. It learned how to get out of the way of application development and shifted to a Plain Old CLR Objects (POCOs) model, enabling testing and domain-focused software development without disenfranchising data-focused developers. It addressed performance issues and numerous concerns about the quality of generated code, and won over many database administrators (DBAs) along the way.
Beginning with EF 4.1, Microsoft recognized the complexity EF required and simplified access to its functionality by introducing the DbContext API. At the same time, because not everyone wants to use a designer or generated code, it provided the ability to build models with your own code. Along the way, there was another significant change that wasn’t about features, syntax, code or performance. The EF team became more transparent and interactive with its community of users, and it began to provide feature releases more fluently rather than binding them to the Microsoft .NET Framework. This led to two advances after EF5 was released in 2012. First, all of the Entity Framework APIs were extracted from the .NET Framework and combined with the out-of-band feature APIs on which the team was also working. Second, the entire development effort moved to an open source model. EF6 has been developed publicly on entityframework.codeplex.com. Not only can you see what the team is doing via meeting notes, check-ins, and downloadable nightly builds, but you can also contribute source to EF6 (though with complete oversight by the EF team).
Keep in mind that EF6 is an evolution, not a revolution. Almost everything you already know about EF stays the same, such as how you build Entity Framework models and how you use EF in your applications. EF6 advances the ORM, but doesn’t change how it fundamentally works. If you’ve invested in learning EF, that investment continues to pay off. EF6 doesn’t come without some breaking changes—but these are limited to some namespace alterations that are easy enough to deal with if you’re prepared. I’ll point you to resources for guidance at the end of this article.
I think of EF6 features in a few categories:
- Features that come for free: These are capabilities that are part of the core. You don’t even have to know they’re there to benefit from them, much less learn any new coding. This group includes features such as performance gains brought by a rewritten view-generation engine and query compilation modifications, stability granted by the ability of DbContext to use an already open connection, and a changed database setting for SQL Server databases created by Entity Framework.
- Level-setting features: A major enhancement is that Code First now supports mapping to Stored Procedures, something that has been supported by models created in the designer. This feature has gotten a lot of coverage in Channel 9 videos (such as the one at bit.ly/16wL8fz) and in a detailed spec on the CodePlex site, so I won’t repeat the information in this article.
- Another change is more interesting. As I mentioned, with EF6, the EF APIs have been extracted from the .NET Framework; they’re now completely encapsulated in the NuGet package. This means that certain features introduced with EF5—such as enum and spatial data support and improved performance—are no longer dependent on .NET 4.5. So if you’re using .NET 4with EF6, you can finally benefit from those features.
- I’d also include the EF Designer in this category. It has been moved out of Visual Studio as of the 2013 edition, and instead provided as an extension to Visual Studio. For EF6, having the designer as an extension is a huge bonus. Going forward, the team will be able to add features directly to the designer, including those that are currently provided in the Entity Framework Power Tools. Separating the designer from Visual Studio allowed Microsoft to ship EF6 tooling for Visual Studio 2012 as well as Visual Studio 2013.
- Ninja features: These are features you’ve craved ever since you got past the basic EF sample applications. There are many such features in EF6: support for asynchronous queries and saves, the return of custom Code First conventions, more extensibility using the new DbConfiguration type (which relies on the low-level EF6 IDbDependencyResolver), support for mocking in unit tests, configurable retries on spotty connections, and even more. You don’t need to be a certified ninja to use these features—but you’ll certainly feel like one when you do!
I also want to highlight a special category: EF6 contributions that came from community members. Unai Zorrilla added DbSet.AddRange and RemoveRange, the ability to customize pluralization and the handy DbChangeTracker.HasChanges method. He’s also working on other cool features for a future iteration of EF. Erik Jensen, a SQL Server Compact (SQLCE) MVP, contributed SQLCeFunctions, which are similar to the SqlFunctions for using SQL Server functions in LINQ to Entities queries. The greatly improved speed of EF view generation—most dramatic for large, complex models—was driven by Alireza Haghshenas and a CodePlex member named VSavenkov. It’s also possible now to define custom migration operations, thanks to Iñaki Elcoro, aka iceclow on CodePlex. (Rowan Miller of the EF team wrote some blog posts about this feature; the first is at bit.ly/ZBU0w1.) A full list of contributors can be found in the team blog post, “EF6 RTM Available,” at bit.ly/1gmDE6D.
In this article, I’ll drill into some of the less-publicized topics and point you to existing resources to learn more about the others.
A Version History page on the MSDN Data Developer Center (bit.ly/1gCT0nz) lists all of the features, each with a sentence or two of detail and some with links to more information.
It Just Works: Performance Improvements and Stability
Performance is the bane of many a software project and there has been plenty of criticism of the performance of Entity Framework since its inception. However, each iteration of EF has brought vast improvements in this area.
One of the biggest drags on performance is the startup time involved with the first use of a context in an application process. You can do a lot to improve that startup time, though. Hopefully you’ve already learned these tricks from my own writing or other resources, such as the MSDN doc on performance considerations at bit.ly/3D6AiC.
A startup step that often hampers performance is the view generation of mapping views, where EF creates the relevant SQL to query against each of the entity sets in the model. These views get leveraged as your app runs so that for certain queries, EF doesn’t have to work out the SQL on the fly. View generation happens whether you created your model with the EF Designer or with Code First. You can pre-generate these views and compile them into the application to save time.
For large, complex models, view generation was especially time-consuming. This process has been revamped for EF6, improving the speed dramatically, whether you pre-generate the views or let this happen at run time. Note that there was a bug in the EF 6.0.0 release that hindered this feature, but it was corrected in EF 6.0.1, which was released on the same day and is (at the time of writing) the default package that you’ll get via NuGet. Additionally, the way EF uses those generated views at run time has been enhanced, improving query execution time. View generation on small or simple models was never an issue. But plenty of organizations have models with hundreds of entities that also include inheritance, relationships and other complications. Those organizations will benefit greatly from this change.
On another performance note, see the guidance about using Ngen against the Entity Framework assembly in the announcement blog post for the release of EF6 at bit.ly/1gmDE6D.
Faster LINQ Contains Compilation The EF team continues to tweak how queries are created, and one change the team has highlighted is how queries using LINQ Contains are compiled. To be clear, it’s the performance of the compilation process that has improved. The generated SQL hasn’t changed, so the execution of the query in the database isn’t affected.
SQL Server Database Creation One of the stability improvements in EF6 is related to database creation. Both the Model First and Code First workflows can create a database for you. If that database is SQL Server, EF is now aligned with a “best practice” for SQL Server databases, which is to configure the database’s READ_COMMITTED_SNAPSHOT setting to ON. This means that, by default, the database will create a snapshot of itself every time a change is made. Queries will be performed on the snapshot while updates are performed on the actual database. I wrote about this feature in a recent blog post, “What’s that Read_Committed_Snapshot Transaction Support for EF6 About Anyway?” at bit.ly/14FDpZI.
Reuse Open Connections Finally, a frustrating limitation has been removed: EF6 lets you execute context calls on an open DbConnection. In the past, if you explicitly opened a connection before executing the EF command that used that connection, or you attempted to reuse a connection that had already been opened by another context call, an exception would be thrown with the message “Entity Connection can only be constructed with a closed DbConnection.” Now, EF6 is more than happy to let you reuse an already open connection.
Ninja Enhancements
Async Support I explored a handful of new features—Async querying, SaveChanges and custom conventions—in “Playing with the EF6 Alpha,” in my March 2013 Data Points column (msdn.microsoft.com/magazine/jj991973).
Async support brings the .NET 4.5 Await and Async pattern to the LINQ query execution methods for EF, giving you FirstAsync, FirstOrDefaultAsync, SingleAsync, SingleOrDefaultAsync, ToListAsync, ForEachAsync and more. To see the full list, check System.Data.Entity.QueryableExtensions. DbSet gained FindAsync and DbContext gained SaveChangesAsync. Since that article, not much has changed, so you can take a look at it to get more details. In addition, Microsoft created some walk-throughs and an interesting detailed specification, which you can get to from the version history page I mentioned earlier.
Custom Code Conventions I also wrote about custom Code First conventions in that article—another ninja feature, for sure. The EF team worked on this for the initial release of Code First, but it was holding up the release and the team was forced to set it aside—to the disappointment of many developers.
Suppose you have a common mapping you want to apply as a general rule to your entities or properties. Now you can define it as a convention rather than having to specify the mapping individually for each entity or property in your model, and it will be applied across the board. For example, if you want each string property to be represented in your database as 50 characters, instead of whatever default your database provider uses, you can specify this rule as a convention. The conventions leverage the Code First Fluent API, so building conventions should feel familiar if you’ve configured mappings this way:
modelBuilder.Properties<String>().Configure(p => p.HasMaxLength(50))
Now, every string in this model will be mapped to a database column of 50 characters. As with the Fluent or annotations configurations, you can specify conventions for properties or entities, and control inheritance mappings. Affecting relationships via convention is a less common and more complex task handled by model-based conventions. For more information, see bit.ly/1gAqcMq. You can also use a convention as a data annotation. There’s a hierarchy for executing conventions when Code First is building its model. By default, built-in conventions run first and custom conventions run afterward. But you can force a custom convention to precede a built-in convention. Check out “Custom Code First Conventions” at bit.ly/14dg0CP for examples.
Connection Resiliency If a connection is dropped while EF is attempting to execute a query or save changes, you now have the ability to tell EF to retry. Though dropped connections can be a problem on corporate intranets, connection resiliency has proven to be quite useful in helping apps that connect to the cloud. The retries can be configured using IDbConnectionStrategy. The SQL Server provider included with EF specifies a default:SqlServerExecutionStrategy, which has an error message suggesting that you tune the strategy for exceptions thrown by transient connections. Another, SqlAzureExecutionStrategy, is tuned for connections to Windows Azure SQL Database.
The simplest way to specify a strategy is with the new DbConfiguration class, which makes it easy to configure how a particular database provider should behave. The following tells EF to use SQLAzureExecutionStrategy for SqlClient:
SetExecutionStrategy (SqlProviderServices.ProviderInvariantName,
() => new SqlAzureExecutionStrategy());
Not only are the connection strategies configurable, but you can also create your own as well as suspend them programmatically as needed. EF team member Miller shows you how to suspend in his blog post at bit.ly/14gPM1y.
I tested SqlAzureExecutionStrategy using a trick suggested by another EF team member, Glenn Condron. To trigger the particular transient connection fault error codes that this strategy looks for, I used the new EF6 command interception feature to throw a transient connection error. Then I ran a test whose output showed that when I set the execution strategy, the query was retried five times after the initial failure. There’s a great comment on my blog post about this feature from a developer who says his company is already witnessing the benefits of this feature (bit.ly/HaqMA0).
There’s also an interesting algorithm that ensures retries on different threads don’t all execute at the same time.
Share DbTransactions and DbConnections I hope you’re aware by now that EF always uses a DbTransaction by default for calls made to the database. For example, when calling SaveChanges, a DbTransaction is created before the first command is sent to the database. EF then sends all necessary insert, update and delete commands to the database, and finally commits the transaction. If one command fails, all of the previously executed commands are rolled back.
You’ve always had the ability to override that default behavior by spinning up a TransactionScope to wrap the EF call and any other calls (not necessarily database- or EF-related) that need to be in the same transaction. An addition to EF6 now lets a single DbTransaction be responsible for multiple database calls. Note that you’ll still need to use a TransactionScope if you want to include non-database logic within the transaction or distributed transactions for calls to different databases.
The key to sharing DbTransactions with EF6 is a new BeginTransaction method that returns a reference to the current DbTransaction and a UseTransaction method.
This code demonstrates the default behavior:
//code to create two new casinos, "casino1" & "casino2"
var context = new CasinoSlotsModel();
context.Casinos.AddRange(new[] { casino1, casino2 });
context.SaveChanges();
context.Database.ExecuteSqlCommand
("Update Casino.Casinos set rating= " +
(int) casino.Rating)
My profiler shows a transaction being used around each context call—one to SaveChanges, which triggered two inserts, and one to ExecuteSqlCommand, which triggered the update—as shown in Figure 1.
Figure 1 Commands from Separate Context Calls Wrapped in Their Own Transactions
Now I’ll modify the code to share a transaction, wrapping the SaveChanges and ExecuteSqlCommand calls. I’ll use the new DbContext.Database.BeginTransaction to explicitly instantiate a System.Data.Entity.DbContextTransaction, and open a connection if necessary (keep in mind that there’s a similar command with DbContext.Database.Connection, but that returns a System.Data.Common.DbTransaction, which can’t be shared by the EF commands):
using (var tx = context.Database.BeginTransaction()) {
try {
context.SaveChanges();
context.Database.ExecuteSqlCommand
("Update Casino.Casinos set rating= " +
(int) casino.Rating);
tx.Commit();
}
catch (Exception) {
tx.Rollback();
}
}
You can see in Figure 2 that all of the commands are wrapped in the same transaction.
Figure 2 Commands from All Context Calls in a Single Transaction
There’s another new feature called UseTransaction. You can spin up a DbTransaction and then use it for ADO.NET calls and, with DbContext.Database.UseTransaction, execute EF calls even from separate context instances within the same transaction. You can see an example of this at bit.ly/1aEMIuX.
It’s also possible to explicitly reuse an open connection, because EF can now create an EntityConnection (something the ObjectContext does in the background) with an already opened connection. Also, a context won’t close a connection that it didn’t open itself. I wrote a simple test in which I open a context’s connection before executing a call from the context:
[TestMethod]
public void ContextCanCreateEntityConnectionWithOpenConnection()
{
using (var context = new CasinoSlotsModel())
{
context.Database.Connection.Open();
Assert.IsNotNull(context.Casinos.ToList());
}
}
When executing the ToList call, the DbContext will create an ObjectContext instance that in turn will create an EntityConnection. It then uses the EntityConnection to open the DbConnection and closes the DbConnection when the call is complete with all results returned. Running this in EF5 causes an exception (“EntityConnection can only be constructed with a closed DbConnection”), but it succeeds in EF6 because of the change in behavior. This change will allow you to reuse connections in scenarios where you want to have more control over the state of connection. The specs suggest scenarios “such as sharing a connection between components where you cannot guarantee the state of the connection.”
AddRange and RemoveRange As mentioned earlier, AddRange and RemoveRange are contributions from community member Zorrilla. Each method takes as its parameter an enumerable of a single entity type. In the first code sample in the sharing DbTransactions section, I used AddRange when I passed in an array of Casino instances:
context.Casinos.AddRange(new[] { casino1, casino2 });
These methods execute much faster than adding or removing a single object at a time because, by default, Entity Framework calls DetectChanges in each Add and Remove method. With the Range methods, you can handle multiple objects while DetectChanges is called only once, improving performance dramatically. I’ve tested this using five, 50, 500, 5,000 and even 50,000 objects and, at least in my scenario, there’s no limit to the size of the array—and it’s impressively fast! Keep in mind that this improvement is only relevant in getting the context to act on the objects, and has no bearing on SaveChanges. Calling SaveChanges still executes just one database command at a time. So while you can quickly add 50,000 objects into a context, you’ll still get 50,000 insert commands executed individually when you call SaveChanges—probably not something you want to do in a real system.
On the flip side of this, there were long discussions about implementing support for bulk operations without requiring objects to be tracked by EF (bit.ly/16tMHw4), and for batch operations to enable sending multiple commands together in a single call to the database (bit.ly/PegT17). Neither feature made it into the initial EF6 release, but both are important and slated for a future release.
Less Interference with Your Coding Style In .NET, it’s possible to override the System.Object.Equals method to define your system’s rules for equality. Entity Framework, however, has its own way of determining the equality of tracked entities, and this relies on identity. If you’ve overwritten Equals (and the GetHashCode method that Equals is dependent upon), you can trip up the change-tracking behavior of Entity Framework. Petar Paar demonstrates this problem very clearly in his blog post at bit.ly/GJcohQ. To correct this problem, EF6 now uses its own Equals and GetHashCode logic to perform change-tracking tasks, ignoring any custom Equals and GetHashCode logic you may have written. However, you can still make explicit calls to your own custom methods in your domain logic. This way, the two approaches can live in harmony.
If you’re focused on graphs and aggregates, you may want to nest types within other types. But the Code First model builder wasn’t able to discover nested types to create entities or complex types in a model. Figure 3 shows an example of nested type: Address. I’ll use Address only in the Casino type, so I’ve nested it in the Casino class. I’ve also created Address as a Domain-Driven Design (DDD) value object because it doesn’t need its own identity. (See my October 2013 Data Points column, “Coding for Domain-Driven Design: Tips for Data-Focused Devs, Part 3,” at msdn.microsoft.com/magazine/dn451438 for more about DDD value objects.)
Figure 3 My Casino Class with a Nested Address Type
public class Casino()
{
//...other Casino properties & logic
public Address PhysicalAddress { get; set; }
public Address MailingAddress { get; set; }
public class Address:ValueObject<Address>
{
protected Address(){ }
public Address(string streetOrPoBox, string city,
string state,string postalCode)
{ City = city;
State = state;
PostalCode = postalCode;
StreetOrPoBox = streetOrPoBox; }
public string StreetOrPoBox { get; private set; }
public string City { get; private set; }
public string State { get; private set; }
public string PostalCode { get; private set; }
}
}
I used the EF Power Tools to get a visual representation of the model, and in Figure 4, I show the resulting Casino entity rendered when using EF5 and EF6. EF5 didn’t recognize the nested type and didn’t include Address or the dependent properties (PhysicalAddress and MailingAddress) in the model. But EF6 was able to detect the nested type, and you can see the Address fields were represented in the model.
Figure 4 Unlike EF5, EF6 Sees the Nested Address Type and Includes the Dependent Properties
The same under-the-covers changes that enable the nested types also solve another problem. This is the problem raised by having multiple types with the same names under different namespaces in the same project. Previously, when EF read the metadata from the EDMX and looked for the matching type in the assembly, it didn’t pay attention to namespaces.
A common scenario where this caused issues was including non-EF representations of entities in the same project as the model that contained the entities. So I might have this code-generated PokerTable class from my model:
namespace CasinoEntities
{
public partial class PokerTable
{
public int Id { get; set; }
public string Description { get; set; }
public string SerialNo { get; set; }
}
}
I might also have this DTO class that’s not part of my model but is in the same project:
namespace Casino.DataTransferObjects
{
public class PokerTable
{
public int Id { get; set; }
public string Description { get; set; }
public string SerialNo { get; set; }
}
}
When the project targets EF5, you’ll see the following error when building the project:
The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type ‘PokerTable.’ Previously found CLR type ‘MyDtos.PokerTable,’ newly found CLR type ‘EDMXModel.DTOs.PokerTable.’
You’ll see this error at design time with an EDMX. With Code First, if you had the same scenario—two matching classes with the same name but different namespaces, and one of those classes in the model—you’d see the problem at run time when the model builder begins interpreting the Code First model.
This problem has long been a source of frustration. I’ve read that message and asked my computer: “Do you not see the different namespaces? Hello?” I also have a collection of e-mails from friends, clients and other developers who have experienced this problem.
EF6 will now recognize the namespaces and allow this scenario. You can read more about the internals that enabled these two changes in the blog post by Arthur Vickers at bit.ly/Wi1rZA.
Move Context Configuration into Code There are a number of settings you can apply in your app.config or web.config files to define how your context should work. For example, you can specify a database initialization or migration or a default database provider. My method of adding these has often been copying and pasting because the settings are too hard to remember and involve a lot of strings. Now, with EF6, you can declare many context configurations in code using the DbConfiguration class. I played with this in the March Data Points column, but encountered a bug caused by a race condition, which I reported and has since been fixed. So I’ll revisit DbConfigurations (also referred to as code-based configuration) now. Note that there’s plenty of room for confusion when talking about configuration mappings for Code First versus DbConfiguration settings versus DbMigrationConfigurations for defining how database migration will work when you change your model. DbConfiguration is targeted at DbContext settings.
DbConfiguration depends on another super-ninja, low-level feature of EF6: support for dependency resolution, similar to the IDependencyResolver used in ASP.NET MVC and Web API. Dependency resolution allows you to use the Service Locator pattern with the Inversion of Control (IoC) pattern in your code, allowing EF6 to choose from a hierarchy of available objects that implement a common interface. In this case the root interface is IDbDependencyResolver. While EF6 includes a number of DbConfigurations that allow it to discover and place precedence on the context settings, it’s possible to leverage dependency resolution to add new features to EF as well. I’ll stick to showing some of the configurations and point you to the feature spec at bit.ly/QKtvCr for more details about the IDbDependencyResolver.
You can use DbConfiguration to specify familiar context rules as well as settings that are new to EF6. Figure 5 shows a sample configuration class that includes a host of different settings EF will use in place of its default behaviors. Notice the settings are placed in the class constructor.
Figure 5 Sample Configuration Class
public class CustomDbConfiguration : DbConfiguration
{
public CustomDbConfiguration()
{
SetDefaultConnectionFactory(new LocalDbConnectionFactory("v11.0"));
SetDatabaseInitializer
(new MigrateDatabaseToLatestVersion<CasinoSlotsModel, Configuration>());
//SetDatabaseInitializer(new MyInitializer());
SetExecutionStrategy("System.Data.SqlClient",
() => new SqlAzureExecutionStrategy());
AddInterceptor(new NLogEfCommandInterceptor());
SetPluralizationService(new CustomPluralizationService());
}
}
SetDefaultConnectionFactory supplants the DefaultConnectionFactory tag you may already be using in your config file in the entityframework section. SetDatabaseInitializer replaces specifying an initializer or migration configuration in your config file or at application startup. I show two examples, though one is commented out. SetExecutionStrategy lets you specify what to do if your connection drops in the middle of EF queries or other execution commands. SetPluralizationService exposes another new feature of EF6: the ability to create custom pluralizations. I’ll explain more in a bit.
There are a slew of other ways to affect the context with these built-in dependency resolvers. The MSDN document, “IDbDependencyResolver Services” (bit.ly/13Aojso), lists all of the resolvers that are available with DbConfiguration. Dependency resolution is also used to help provider writers solve certain issues when they need to inject rules and logic into how the context interacts with the provider.
Query and Command Interception I failed to mention CustomDbConfiguration’s use of AddInterceptor. DbConfiguration lets you do more than shove in IDbDependencyResolvers. Another new feature of EF6 is the ability to intercept queries and commands. When intercepting queries and commands, you now have access to the generated SQL that’s about to be sent to the database and results that are coming back from those commands. You can use this information to log the SQL commands or even modify them and tell EF to use the updated commands. Although I enjoyed playing with this feature, I’ll save some space by pointing you to Part 3 of Arthur Vickers’ three-part blog series on it: “EF6 SQL Logging – Part 3: Interception building blocks” (bit.ly/19om5du), which has links back to Part 1 (“Simple Logging”) and Part 2 (“Changing the content/formatting”).
Customize EF Pluralization Before talking about the ability to customize EF pluralization, I want to be sure you understand its default behavior. EF uses its internal pluralization service for three tasks:
- In Database First, it ensures that entities have a singularized name. So if your database table is named People, it will become Person in the model.
- In the EF Designer for Database or Model First, it creates pluralized EntitySet names (the basis of DbSets) based on the Entity name. For example, the service will be sure that the EntitySet name for the Person entity is People. It doesn’t just use the table name if you created the model using Database First.
- In Code First, where you explicitly name the DbSets, EF uses the service to infer table names. If you’re starting with a class named Person, convention will assume that your database table is named People.
The service doesn’t work like spelling dictionaries, where you can provide a textual list of custom spellings. Instead it uses internal rules. Aside from the occasional anomaly (I had fun with the entity name Rhinoceros early on), the biggest problem with the service is that the rules are based on English.
For EF6, Zorrilla created the IPluralizationService interface so you can add your own logic. Once you’ve created a custom service, you can plug it in with DbConfiguration as shown earlier.
Currently this customization will only work with the third case in the previous list: when Code First is inferring the table names. As of the initial EF6 release, the customization can’t be applied to the designer.
There are two ways to use the service. You can start with a base service—either the EnglishPluralizationService in EF or one that someone else already built—and then override the Singularize or Pluralize methods to add your own rules. Additionally you can specify a pair of words in a CustomPluralizationEntry class and attach the class to an existing service. Zorrilla demonstrates the CustomPluralizationEntry in his blog post (bit.ly/161JrD6).
Look for a future Data Points column in which I’ll show an example of adding rules (not just word pairs) for pluralization, with a demonstration of the effect on Code First database mappings.
More Code First Goodies
There are a handful of new features targeting Code First that I haven’t covered yet—specifically, Code First migrations. For reasons of space, I’ll highlight them here and follow up with a more in-depth look in the January 2014 Data Points column:
- Ability to create migration scripts that can check to see which have been run already so you can fix up a database from any migration point.
- More control over the Migrations_History table to account for different database providers.
- Ability to specify default schema for database mapping instead of always defaulting to dbo.
- Ability of migrations to handle different DbContexts that target the same database.
- Ability of ModelBuilder to add multiple EntityTypeConfigurations at once rather than using one line of code for each.
Go Get Ninja!
In my opinion, the most important thing to remember about EF6 is that it adds great features to what already exists in EF. If you’re moving projects from EF5 to EF6, you should be aware of some namespace changes. The team has detailed guidance for making this move at bit.ly/17eCB4U. Other than that, you should feel confident about using EF6, which is now the current stable version of Entity Framework that’s distributed through NuGet. Even if you don’t intend to use any of the ninja features right away, remember that you’ll still benefit from increased performance as described earlier in this article. I’m most excited about the ninja features, though, and grateful to the developers from the community who’ve added to EF6 as well.
EF will continue to evolve. While the first release of EF6 was timed to coincide with the release of Visual Studio 2013, EF 6.1 and versions beyond that are already in the works. You can follow their progress on the CodePlex site.
Julie Lerman is a Microsoft MVP, .NET mentor and consultant who lives in the hills of Vermont. You can find her presenting on data access and other Microsoft .NET topics at user groups and conferences around the world. She blogs at thedatafarm.com/blog and is the author of “Programming Entity Framework” (2010) as well as a Code First edition (2011) and a DbContext edition (2012), all from O’Reilly Media. Follow her on Twitter at twitter.com/julielerman and see her Pluralsight courses at juliel.me/PS-Videos.
Thanks to the following technical expert for reviewing this article: Rowan Miller (Microsoft)