Entity framework — Литература по Entity Framework


Работа с Entity Framework 6

является продолжением технологии Microsoft ActiveX Data и предоставляет возможность работы с базами данных через объектно-ориентированный код C#. Этот подход предоставляет ряд существенных преимуществ: вам не нужно беспокоиться о коде доступа к данным, вам не нужно знать деталей работы СУБД SQL Server и синтаксиса языка запросов T-SQL, вместо этого вы работаете с таблицами базы данных как с классами C#, с полями этих таблиц — как со свойствами классов, а синтаксис SQL-запросов, который в ADO.NET раньше нужно было вставлять в код C# в виде команд, заменен на более удобный подход с LINQ. Entity Framework берет на себя обязанности по преобразованию кода C# в SQL-инструкции.

При работе с Entity Framework вам предоставляются огромные возможности по созданию модели базы данных с помощью интегрированной среды разработки (IDE) Visual Studio. Начиная с версии Entity Framework 4.1 вам предоставляется три подхода по проектированию базы данных, из которых вы можете выбрать для себя подходящий:

Database-First

Подходит для проектировщиков баз данных — сначала вы создаете базу данных с помощью различных инструментов (например, SQL Server Management Studio), а затем генерируете EDMX-модель базы данных (предоставляет удобный графический интерфейс для взаимодействия с базой данных в виде диаграмм и объектную модель в виде классов C#). В данном случае вам нужно работать с SQL Server и хорошо знать синтаксис T-SQL, но при этом не нужно разбираться в C#.

Model-First

Подходит для архитекторов — сначала вы создаете графическую модель EDMX в Visual Studio (в фоновом режиме создаются классы C# модели), а затем генерируете на основе диаграммы EDMX базу данных. При данном подходе не нужно знать ни деталей T-SQL ни синтаксиса C#.

Code-First

Подходит для программистов — при данном подходе модель EDMX вообще не используется и вы вручную настраиваете классы C# объектной модели (данный подход поддерживает как генерацию сущностных классов из существующей базы данных, так и создание базы данных из созданной вручную модели объектов C#). Очевидно, что это подходит для программистов, хорошо знакомых с синтаксисом C#.

Лично я при работе с Entity Framework выбираю подход Code-First, но в нашем руководстве мы рассмотрим все три подхода.

Entity framework — Литература по Entity Framework

Название: Entity Framework Tutorial, 2nd edition
Автор: Joydip Kanjilal
Издательство: Packt Publishing
Год: 2015
Формат: PDF, EPUB
Размер: 33 Мб
Язык: английский / English

The ADO.NET Entity Framework from Microsoft is a new ADO.NET development framework that provides a level of abstraction for data access strategies and solves the impedance mismatch issues that exist between different data models.

This book explores Microsoft’s Entity Framework and explains how it can used to build enterprise level applications. It will also teach you how you can work with RESTful Services and Google’s Protocol Buffers with Entity Framework and WCF. You will explore how to use Entity Framework with ASP.NET Web API and also how to consume the data exposed by Entity Framework from client applications of varying types, i.e., ASP.NET MVC, WPF and Silverlight.

You will familiarize yourself with the new features and improvements introduced in Entity Framework including enhanced POCO support, template-based code generation, tooling consolidation and connection resiliency. By the end of the book, you will be able to successfully extend the new functionalities of Entity framework into your project.

EntityFramework — популярные книги

ISBN: 978-1449312947
Год издания: 2011
Издательство: O’Reilly Media
Язык: Английский

Take advantage of the Code First data modeling approach in ADO.NET Entity Framework, and learn how to build and configure a model based on existing classes in your business domain. With this concise book, you’ll work hands-on with examples to learn how Code First can create an in-memory model and database by default, and how you can exert more control over the model through further configuration.

Code First provides an alternative to the database first and model first approaches to the Entity Data Model. Learn the benefits of defining your model with code, whether you’re working with an existing database or building one from scratch. If you work with Visual Studio and understand database management basics, this book is for you.

Learn exactly what Code First does—and does not—enable you to do
* Understand how property attributes, relationships, and database mappings are inferred from your classes by Code First
* Use Data Annotations and the Fluent API to configure the Code First data model
* Perform advanced techniques, such as controlling the database schema and overriding the default model caching

This book is a continuation of author Julia Lerman’s Programming Entity Framework, widely recognized as the leading book on the topic.

Entity Framework: как быстрее написать код для работы с базой данных

Код взаимодействия с базой данных может быть очень громоздким, однако его можно сократить, воспользовавшись Entity Framework.

Entity Framework — это решение для работы с базами данных, которое используется в программировании на языках семейства.NET. Оно позволяет взаимодействовать с СУБД с помощью сущностей (entity), а не таблиц. Также код с использованием EF пишется гораздо быстрее.

Например, работая с базами данных напрямую, разработчик должен беспокоиться о подключении, подготовке SQL и параметров, отправке запросов и транзакций. На Entity Framework всё это делается автоматически — программист же работает непосредственно с сущностями и только говорит EF, что нужно сохранить изменения.

В этой статье будут разобраны основы применения Entity Framework, для понимания которых нужно владеть ADO.NET — пользоваться базами данных, писать SQL-запросы и работать с подключениями.

Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Как установить
Entity Framework

Подключить Entity Framework можно к любому проекту — от Xamarin до ASP.NET. Однако, чтобы не отвлекаться на работу с интерфейсом, здесь мы рассмотрим консольное приложение.

Для начала создайте проект Console Application в Visual Studio. Затем откройте менеджер пакетов NuGet:

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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 IDbDependency­Resolver), 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.Add­Range 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 gener­ation 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:

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:SqlServer­ExecutionStrategy, 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:

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:

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):

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:

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:

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

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:

I might also have this DTO class that’s not part of my model but is in the same project:

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

SetDefaultConnectionFactory supplants the DefaultConnection­Factory 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, “IDbDepen­dencyResolver 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:

  1. 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.
  2. 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.
  3. 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)

Entity Framework Core 2 для ASP.NET Core MVC для профессионалов

Pro Entity Framework Core 2 for ASP.NET Core MVC
Adam Freeman


Тираж данной книги закончился.

Введение

Файлы к книге

Эффективно моделируйте, отображайте и получайте доступ к данным с помощью Entity Framework Core 2 — новейшего выпуска инфраструктуры объектно-реляционного отображения от Microsoft. Вы получите возможность обращаться к данным с использованием объектов .NET через самый распространенный уровень доступа к данным, применяемый в проектах ASP.NET Core MVC 2.

Автор многочисленных бестселлеров Адам Фримен объясняет, как извлечь максимальную пользу из Entity Framework Core 2 в проектах MVC. Сначала он описывает различные способы моделирования данных посредством инфраструктуры Entity Framework Core 2 и разнообразные типы баз данных, которые могут применяться. Затем он показывает, каким образом использовать Entity Framework Core 2 в собственных проектах MVC, начиная с основных элементов и заканчивая наиболее сложными и развитыми функциональными возможностями, и в ходе изложения предоставляет вам все необходимые знания.

Благодаря этой книге, вы .

  • Обретете глубокое понимание архитектуры Entity Framework Core 2
  • Научитесь создавать базы данных с применением модели данных MVC
  • Узнаете, как создавать модели MVC с использованием существующей базы данных
  • Обеспечите доступ к данным в приложении MVC с применением Entity Framework Core 2
  • Научитесь использовать Entity Framework в веб-службах REST

Каждая тема раскрывается кратко и понятно с приведением всех деталей, необходимых для подлинно эффективного освоения.

Наиболее важным средствам дается всеобъемлющее толкование, при этом в главах затрагиваются часто возникающие проблемы и предлагаются способы их избегания.

Книга обсуждается в отдельном сообщении в блоге Виктора Штонда.

формат 70×100/16; серия Expert’s Voice (APress) ; 20.02.2020; Вильямс.

Понравилась книга? Порекомендуйте её друзьям и коллегам:

Часть I. Введение в инфраструктуру Entity Framework Core 2 17
Глава 1. Основы Entity Framework Core 18
Глава 2. Ваше первое приложение Entity Framework Core 21
Глава 3. Работа с базами данных 37
Глава 4. SportsStore: реальное приложение работы с данными 58
Глава 5. SportsStore: хранение данных 68
Глава 6. SportsStore: модификация и удаление данных 90
Глава 7. SportsStore: расширение модели данных 111
Глава 8. SportsStore: масштабирование 140
Глава 9. SportsStore: интерфейс для покупателей 163
Глава 10. SportsStore: создание веб-службы REST 187
Часть II. Подробные сведения об инфраструктуре Entity Framework Core 2 205
Глава 11. Работа с Entity Framework Core 206
Глава 12. Выполнение операций над данными 237
Глава 13. Работа с миграциями 261
Глава 14. Создание отношений между данными 294
Глава 15. Работа с отношениями, часть 1 326
Глава 16. Работа с отношениями, часть 2 361
Глава 17. Формирование шаблонов для существующих баз данных 391
Глава 18. Ручное моделирование баз данных 418
Часть III. Расширенные возможности инфраструктуры Entity Framework Core 2 447
Глава 19. Работа с ключами 448
Глава 20. Запросы 477
Глава 21. Хранение данных 505
Глава 22. Удаление данных 540
Глава 23. Использование возможностей сервера баз данных 564
Глава 24. Использование транзакций 602
Предметный указатель 620

Новые возможности в июньской CTP-версии Entity Framework

Срикант Мандади

Продукты и технологии:

Entity Framework 4.2, Visual Studio 2010

В статье рассматриваются:

  • новые средства — перечислимые, табличные функции (table-valued functions) и пространственные типы;
  • использование подходов Code First и Database First;
  • автоматически компилируемые LINQ-запросы.

Недавно выпущенная CTP-версия Microsoft Entity Framework (EF) за июнь 2011 г. включает поддержку ряда средств, о введении которых нас часто просили, в частности перечислимых и пространственных типов, а также функций, возвращающих табличные значения (table-valued functions, TVF) (далее для краткости — табличные функции). Мы рассмотрим эти средства на простых примерах. Я исхожу из того, что вы знакомы с EF (http://bit.ly/oLbjp0) и шаблоном разработки Code First (http://bit.ly/oQ77Hm), введенным в EF 4.1.

Вот что вам понадобится для работы с примерами в этой статье:

  • Visual Studio 2010 Express и SQL Server 2008 R2 Express или выше. Редакции Express продуктов Visual Studio и SQL Server можно скачать по ссылке bit.ly/rsFvxJ.
  • Microsoft EF и EF Tools June 2011 CTP
  • база данных Northwind; ее можно скачать по ссылке bit.ly/pwbDoQ.

Перечислимые типы

Начнем с одного из самых часто запрашиваемых средств в EF — перечислимых. Многие языки программирования, в том числе .NET-языки вроде C# и Visual Basic, изначально поддерживают перечислимые типы. В EF поставлена цель разрешить разработчикам создавать перечислимые типы в своих CLR-типах и сопоставлять с нижележащей Entity Data Model (EDM), после этого сохранять соответствующие значения в базе данных. Прежде чем углубиться в детали, рассмотрим простой пример. Перечислимые поддерживаются в Code First, Database First и Model First. Я начну с подхода Database First (сначала база данных), а затем покажу пример, где используется подход Code First.

Для примера Database First воспользуемся таблицей Products в базе данных Northwind. Прежде чем добавлять модель, переключитесь на EF June 2011 CTP. Для этого сделайте следующее.

  1. Запустите Visual Studio 2010 и создайте новый проект C# Console Application.
  2. Щелкните свой проект правой кнопкой мыши в Solution Explorer и выберите Properties.
  3. Выберите Microsoft Entity Framework June 2011 CTP из раскрывающего списка Target framework (рис. 1).
  4. Нажмите Ctrl+S, чтобы сохранить проект. Visual Studio предложит закрыть проект и заново открыть его — согласитесь, щелкнув Yes.
  5. Добавьте новую модель в проект, выбрав Project | Add New Item (или нажав Ctrl+Shift+A) и указав ADO.NET Data Entity Model в Visual C# Items (мы назовем нашу модель «CTP1EnumsModel.edmx»), затем щелкните Add.
  6. С помощью мастера укажите базу данных Northwind. Выберите таблицу Products и щелкните Finish.
  7. В Entity Model, которая получится в результате такого выбора, содержится одна сущность (Product), как показано на рис. 2.

Рис. 1. Ориентация на Entity Framework June 2011 CTP

Рис. 2. Entity Model для сущности Product

Ниже приведен LINQ-запрос для получения всех продуктов, относящихся к категории Beverages. Заметьте, что CategoryID для Beverages равен 1:

Конечно, чтобы написать этот запрос, вы должны были бы знать, что CategoryID для Beverages равно 1, что возможно лишь в двух случаях: вы запомнили это значение или нашли его, проанализировав базу данных. Другая проблема с этим запросом в том, что непонятно, какую категорию запрашивает этот код. В таком случае нужно либо документировать категорию в каждом месте, где используется CategoryID, либо иметь каждому, кто читает этот код, соответствующие знания о значениях CategoryID для различных категорий.

Еще одна проблема вылезает, когда вы пытаетесь вставить новый Product. Для вставки в таблицу Products используйте следующий код:

Запустив этот код, вы получите от базы данных исключение из-за ограничения внешнего ключа. Это исключение генерируется потому, что категории с идентификатором 13 нет. Было бы куда лучше, если бы у программиста был какой-то способ выяснить список категорий и назначить правильный идентификатор вместо того, чтобы все время помнить набор правильных целочисленных значений.


Давайте введем в модель перечислимые и посмотрим, насколько эту улучшит ситуацию.

Ниже перечислены шаги, необходимые для преобразования CategoryID в перечислимый тип.

  1. Откройте модель в дизайнере, дважды щелкнув файл CTP1EnumsModel.edmx.
  2. Щелкните правой кнопкой мыши свойство CategoryID в Product Entity и выберите Convert to Enum.
  3. 3. Создайте перечислимый тип (enum) и введите значения для его членов в новом диалоге, который появится на экране (рис. 3). Присвойте этому типу имя Category и выберите Byte в качестве нижележащего типа. Нижележащим считается тип, который предоставляет пространство значений для перечислимого типа. Вы можете выбирать его на основе количества членов в перечислении. В данном перечислении восемь членов, что как раз и соответствует байту. Введите эти члены в порядке возрастания значений CategoryID. Укажите Value для первой категории (Beverages) как 1 и оставьте поле Value для остальных членов пустым, потому что их значения автоматически увеличиваются на 1 в базе данных. Этот вариант и для EF является поведением по умолчанию. Но, если бы значения в базе данных были другими, вам пришлось бы заполнять поле Value для каждой категории. Если бы значение для Beverages было 0 вместо 1, вы также могли бы оставить остальные поля пустыми, так как EF выбирает 0 в качестве значения по умолчанию для первого члена перечисления.
  4. Создавая перечислимый тип, вы можете обозначить его как флаг, используя параметр «Is Flag?». Он используется только при генерации кода; если этот флаг установлен, перечислимый тип будет сгенерирован с атрибутом Flags (подробнее о таких перечислениях см. по ссылке bit.ly/oPqiMp). В этом примере оставьте данный параметр неустановленным.
  5. Перекомпилируйте приложение для повторной генерации кода, и полученный в результате этого код будет теперь включать перечислимые.
Цукерберг рекомендует:  React Native —  это возможность быть быстрым

Рис. 3. Окно для создания перечислимого типа

Вы можете переписать запрос для получения всех продуктов, относящихся к категории Beverages, следующим образом:

Теперь IntelliSense будет помогать в написании запроса, и вам не придется изучать базу данных в поисках значений Beverages. Аналогично при обновлениях IntelliSense будет показывать корректные значения для Category.

Мы только что рассмотрели перечислимые, используя подход Database First. А сейчас я применю подход Code First для написания запроса, который возвращает все продукты категории Beverages с использованием перечислимых. Для этого создайте еще одно консольное приложение и добавьте файл исходного кода на C# с типами, показанными на рис. 4..

Рис. 4. Применение перечислимых в подходе Code First

Класс EnumsCodeFirstContext наследует от DbContext — нового типа в EF 4.1, аналогичного ObjectContext, но гораздо более простого в использовании. (Подробнее о применении DbContext API см. по ссылке bit.ly/eeEsyt.)

В коде на рис. 4 стоит обратить внимание на пару моментов.

  • Атрибут Column над свойством Category используется для сопоставления CLR-свойств и столбцов, когда у них разные имена или типы.
  • Конструктор в EnumsCodeFirstContext вызывает конструктор базового класса, передавая строку подключения. По умолчанию DbContext создает базу данных в локальном экземпляре SqlExpress с полным именем класса, производного от DbContext. В этом примере мы просто используем существующую базу данных Northwind.

Теперь вы можете написать код, аналогичный тому, который использовался в контексте Database First, чтобы получить все продукты, относящиеся к категории Beverages:

Другое важное средство, добавленное в эту CTP-версию, — поддержка табличных функций.

Табличные функции

Другое важное средство, добавленное в эту CTP-версию, — поддержка табличных функций (TVF). TVF очень похожи на хранимые процедуры с одним важным отличием: результат, возвращаемый TVF, является компонуемым (composable). Это означает, что результаты от TVF можно использовать во внешнем запросе. Таким образом, главное для разработчиков, использующих EF, заключается в том, что TVF можно указывать в LINQ-запросе, а хранимую процедуру — нет. Я продемонстрирую пример использования TVF в EF-приложении. Попутно вы увидите, как задействовать преимущества функциональности полнотекстового поиска (Full-Text Search, FTS) в SQL Server (подробнее см. по ссылке bit.ly/qZXG9X).

Функциональность FTS предоставляется через несколько предикатов и TVF. В предыдущих версиях EF вы могли задействовать полнотекстовые TVF, либо вызывая их в скрипте на T-SQL с применением ExecuteStoreCommand, либо используя хранимую процедуру. Но оба этих механизма не обеспечивают компонуемость, и их нельзя применять в LINQ to Entities. В моем примере вы увидите, как задействовать эти функции в качестве компонуемых с поддержкой TVF в этой CTP-версии. Для этого я позаимствовал запрос из документации MSDN для ContainsTable (bit.ly/q8FFws). Этот запрос ищет все названия продуктов, в которых есть слова «breads», «fish» или «beers», и этим словам назначаются разные весовые доли (значимость). Для каждой полученной строки, отвечающей этим критериям поиска, показывается относительная близость совпадения (классификационное значение):

Попробуем написать тот же запрос в LINQ to Entities. К сожалению, предоставить ContainsTable напрямую EF нельзя, так как эта инфраструктура ожидает, что в первых двух параметрах имена таблицы и столбца передаются как идентификаторы без кавычек, т. е. как Categories, а не ‘Categories’, и нет никакого способа сообщить EF особым образом интерпретировать эти параметры. Чтобы обойти это ограничение, оберните ContainsTable в другую пользовательскую TVF. Выполните следующий SQL-код для создания TVF с именем ContainsTableWrapper (TVF выполняет функцию ContainsTable применительно к столбцу Description в таблице Categories):

Теперь создайте EF-приложение и используйте эту TVF. Придерживайтесь той же схемы, что и в примере с перечислением, чтобы создать консольное приложение и добавить модель сущностей, связанную с Northwind. Включите Categories, Products и только что созданную TVF. Модель будет выглядеть, как показано на рис. 5.

Рис. 5. Модель сущностей с Products и Categories из Northwind

TVF в рабочей области дизайнера не отображается, но вы можете увидеть ее в Model Browser, раскрыв Stored Procedures/Functions в разделе Store.

Чтобы задействовать эту функцию в LINQ, добавьте функцию-заглушку (function stub) (как описано по ссылке bit.ly/qhIYe2). Я добавил функцию-заглушку в частичный класс для класса ObjectContext — в данном случае NorthwindEntities:

Теперь вы можете пользоваться этой функцией в своих запросах. Просто выведите в консоль Key, т. е. CategoryId и Rank для полнотекстового запроса, упомянутого ранее:

Вывод в консоли выглядит так:

Но это не тот запрос, который мы пытались написать. Нужный нам делает нечто большее. Наряду со значимостью (rank) он предоставляет Category Name и Description, которые интереснее, чем просто Category ID. Вот исходный запрос:

Чтобы использовать LINQ для этого запроса, нужно сопоставить TVF с Function Import в EDM с типом Complex или возвращаемым типом Entity, так как Function Import, которые возвращают Row Types, не являются компонуемыми.

Для сопоставления проделайте следующее.

  1. Дважды щелкните функцию Store в Model Browser, чтобы открыть диалог Add Function Import, показанный на рис. 6.
  2. Введите Function Import Name как ContainsTableWrapperModelFunction.
  3. Установите флажок «Function Import is Composable?».
  4. Выберите функцию ContainsTableWrapper из раскрывающегося списка Stored Procedure/Function Name.
  5. Щелкните кнопку GetColumnInformation, чтобы заполнить таблицу под этой кнопкой информацией о типе результата, возвращаемого функцией.
  6. Щелкните кнопку Create New Complex Type. Это приведет к переключению с Returns a Collection Of на Complex со сгенерированным именем для комплексного типа.
  7. Щелкните OK.

Рис. 6. Сопоставление TVF с Function Import

Для TVF, сопоставленных с Function Import в модели, вам не потребуется добавлять соответствующую функцию в коде, поскольку такая функция будет сгенерирована автоматически.

Теперь вы можете написать запрос на T-SQL, использовавший FTS-функцию ContainsTable в LINQ, следующим образом:

Запустив этот код, вы получите в консоли такой вывод:

Поддержка пространственных типов

Теперь рассмотрим новую функциональность, вызвавшую большой интерес: поддержку пространственных типов. В EDM добавлены два новых типа: DbGeometry и DbGeography. В следующем примере я покажу, как пользоваться пространственными типами в EF с применением Code First.

Создайте проект Console Application с именем EFSpatialSample, затем добавьте в него файл исходного кода на C# со следующими типами:

Свойство Location в Customer имеет тип DbGeography, который был добавлен в пространство имен System.Data.Spatial в этой CTP-версии. DbGeography преобразуется в SqlGeography в случае SQL Server. Вставьте какие-нибудь пространственные данные, используя эти типы, а затем запросите их с помощью LINQ (рис. 7).

Рис. 7. Работа с пространственными данными


Ничего сложного в этом коде не происходит. Вы создаете два объекта Customer с разными местоположениями и указываете их через Well-Known Text (об этом протоколе читайте по ссылке bit.ly/owIhfu). Эти изменения сохраняются в базе данных. Далее запрос LINQ to Entities получает расстояние до каждого клиента в таблице из Customer1. Это расстояние делится на 1609,344 для преобразования метров в мили. Вот вывод программы:

Как и следовало ожидать, расстояние от Customer1 до Customer1 равно 0. Расстояние от Customer1 до Customer2 указано в милях. Операция Distance в запросе выполняется в базе данных с помощью функции STDistance. Ниже показан SQL-запрос, отправляемый базе данных:

Компиляция дерева выражений в SQL создает некоторые издержки — особенно в более сложных запросах.

Автоматически компилируемые LINQ-запросы

В настоящее время, когда вы пишете запрос LINQ to Entities, EF проходит по дереву выражений, генерируемому компилятором C# или Visual Basic, и транслирует (или компилирует) его в SQL. Компиляция дерева выражений в SQL создает некоторые издержки — особенно в более сложных запросах. Чтобы избежать этих издержек при каждом выполнении LINQ-запроса, вы можете компилировать свои запросы, а затем повторно использовать их. Класс CompiledQuery позволяет платить за издержки лишь раз, а затем передает вам делегат, который указывает непосредственно на скомпилированную версию запроса в кеше EF.

Июньская CTP-версия поддерживает новую функциональность Auto-Compiled LINQ Queries, которая позволяет автоматически компилировать и помещать в кеш запросов EF каждый выполняемый вами запрос LINQ to Entities. При каждом последующем выполнении запроса EF будет искать его в своем кеше и не станет снова инициировать весь процесс компиляции. Эта функциональность также ускоряет выполнение запросов, выдаваемых с помощью WCF Data Services, так как «за кулисами» использует LINQ. Подробнее о деревьях выражений см. по ссылке bit.ly/o5X3rA.

Заключение

Как видите, в следующем выпуске EF появится ряд интересных средств. На самом деле их даже больше, чем я смог описать в этой статье, в том числе усовершенствования в генерации SQL-кода для Table per Type (TPT), возможность получения нескольких наборов результатов от хранимых процедур и др. Данная CTP-версия дает шанс ознакомиться с будущими новинками и высказать свои замечания, чтобы разработчики устранили имеющиеся ошибки или улучшили удобство использования новых средств. О любых ошибках можно сообщать через сайт Microsoft Data Developer Connect (connect.microsoft.com/data), а предложения по новой функциональности — через сайт (ef.mswish.net).

Срикант Мандади (Srikanth Mandadi) — руководитель разработок в группе Entity Framework.

Выражаю благодарность за рецензирование статьи группе Entity Framework.

Что такое Entity Framework?

Entity Framework был представлен корпорацией Microsoft в 2008 году как основное средством взаимодействия между приложениями .NET и реляционными базами данных. Entity Framework — это инструмент, упрощающий сопоставление объектов в программном обеспечении с таблицами и столбцами реляционной базы данных.

  • Entity Framework (EF) — это ORM-фреймворк с открытым исходным кодом для ADO.NET , который является частью .NET Framework .
  • ORM обрабатывает создание соединений с базой данных и выполнение команд, а также результаты запросов и автоматическое предоставление этих результатов в качестве объектов приложения.
  • ORM также помогает отслеживать изменения объектов приложения и может сохранять эти изменения в базе данных.

Почему Entity Framework?

Entity Framework — это ORM , нацеленная на повышение производительности за счет сокращения задач по сохранению данных, используемых в приложениях.

  • Entity Framework может генерировать команды базы данных, необходимые для чтения или записи данных, а также выполнять их.
  • При необходимости можно выразить запросы через объекты домена, используя LINQ.
  • Entity Framework выполняет соответствующий запрос в базе данных, а затем предоставляет результаты в экземплярах объектов домена, чтобы вы могли работать с ними в приложении.

На данный момент существуют и другие ORM , такие как NHibernate и LLBLGen Pro . Большинство ORM обычно помещают типы домена непосредственно в схему базы данных.

Entity Framework имеет более сложный уровень отображения, поэтому позволяет настраивать сопоставления. Например, сопоставления единичного объекта с несколькими таблицами базы данных или даже с несколькими объектами в одной таблице.

  • Entity Framework — это рекомендуемая Microsoft технология доступа к данным для новых приложений.
  • ADO.NET также будет непосредственно ссылаться на эту технологию для наборов данных и таблиц данных.
  • Entity Framework — это инструмент, в который активно вкладываются средства и усилия на протяжении уже нескольких лет.
  • Корпорация Microsoft рекомендует использовать Entity Framework с ADO.NET или LINQ для SQL для всех новых разработок.

Концептуальная модель

Для разработчиков, которые ведут проекты, ориентированные на базу данных, преимущество Entity Framework заключается в том, что он позволяет сосредоточиться на бизнес-домене. Хотите, чтобы ваше приложение не ограничивалось только тем, что может сделать база данных?

  • В Entity Framework основное внимание уделяется модели объектов в приложении, а не модели БД, которую вы используете для сохранения данных приложения.
  • Концептуальная модель может быть согласованной со схемой базы данных или кардинально отличаться.
  • Можно использовать Visual Designer для определения концептуальной модели, которая сможет генерировать классы — их вы будете использовать в своем приложении.
  • Можно просто определить классы и использовать функцию Entity Framework под названием Code First . Таким образом вы зададите концептуальную модель для Entity Framework .

В любом случае Entity Framework обрабатывает то, как перейти от вашей концептуальной модели к базе данных. Таки вы можете запросить объекты концептуальной модели и работать с ними напрямую.

Функции

Ниже перечислены основные функции Entity Framework . В этот список вошли наиболее важные функции фреймворка, а также те, о которых разработчики часто задают вопросы.

  • Entity Framework — это инструмент, созданный специалистами компании Microsoft .
  • Entity Framework разрабатывается как продукт с открытым исходным кодом.
  • Entity Framework больше не привязан и не зависит от цикла релизов .NET .
  • Работает с любой реляционной базой данных и с действующим провайдером Entity Framework .
  • Генерация команд SQL из LINQ в Entities .
  • Entity Framework создает параметризованные запросы.
  • Entity Framework позволяет вставлять, обновлять и удалять команды.
  • Работает с визуальной моделью или с вашими собственными классами.
  • Entity Framework поддерживает хранимые процедуры.

Данная публикация представляет собой перевод статьи « What is Entity Framework » , подготовленной дружной командой проекта Интернет-технологии.ру

EntityFramework — популярные книги

ISBN: 978-1449312947
Год издания: 2011
Издательство: O’Reilly Media
Язык: Английский

Take advantage of the Code First data modeling approach in ADO.NET Entity Framework, and learn how to build and configure a model based on existing classes in your business domain. With this concise book, you’ll work hands-on with examples to learn how Code First can create an in-memory model and database by default, and how you can exert more control over the model through further configuration.

Code First provides an alternative to the database first and model first approaches to the Entity Data Model. Learn the benefits of defining your model with code, whether you’re working with an existing database or building one from scratch. If you work with Visual Studio and understand database management basics, this book is for you.

Learn exactly what Code First does—and does not—enable you to do
* Understand how property attributes, relationships, and database mappings are inferred from your classes by Code First
* Use Data Annotations and the Fluent API to configure the Code First data model
* Perform advanced techniques, such as controlling the database schema and overriding the default model caching

This book is a continuation of author Julia Lerman’s Programming Entity Framework, widely recognized as the leading book on the topic.


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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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 IDbDependency­Resolver), 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.Add­Range 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 gener­ation 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.

Цукерберг рекомендует:  25 бесплатных сервисов для веб-дизайнера

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:

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:SqlServer­ExecutionStrategy, 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:

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:

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):


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:

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:

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

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:

I might also have this DTO class that’s not part of my model but is in the same project:

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

SetDefaultConnectionFactory supplants the DefaultConnection­Factory 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, “IDbDepen­dencyResolver 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:

  1. 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.
  2. 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.
  3. 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)

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих