EF6 SQL Logging – Part 3: Interception building blocks

In parts 1 and 2 of this series we looked at how to use DbContext.Database.Log to log the SQL generated by EF. But this code is actually a relatively thin façade over some low-level building blocks for interception in general and, in this case, DbCommand interception in particular. Continue reading

Posted in DbContext API, Entity Framework | Tagged , , | 2 Comments

EF6 SQL Logging – Part 2: Changing the content/formatting

In part 1 we saw how DbContext.Database.Log can be used to easily log SQL to the console or some other TextWriter. This post covers how the context and formatting of the output can be changed.

Continue reading

Posted in DbContext API, Entity Framework | Tagged , , | 5 Comments

EF6 SQL Logging – Part 1: Simple Logging

On the EF team we made a late decision to add some support for interception and logging of generated SQL in EF6. To this end recent checkins have added support for:

  • A Log property for the context similar to DataContext.Log in LINQ to SQL
  • A mechanism to customize the content and formatting of the output sent to the log
  • Low-level building blocks for interception giving greater control/flexibility

(Note that some early iterations of this work will make it into the upcoming beta 1 release, but most of what I describe in these posts came in too late to make it into beta 1. Instead you can try it out using a recent nightly build.)

Continue reading

Posted in DbContext API, Entity Framework | Tagged , , | 8 Comments

EF6: Nested types and more for Code First

Ever since POCO support was introduced in EF4 there have been two limiting restrictions on the types that can be mapped:

  • Types nested inside other types were not supported
  • Types were matched by simple names only

Some recent check-ins to the EF6 code base have lifted these restrictions to some degree when using Code First. This post describes what is now supported, what restrictions still exist, and provides some background about why things are the way they are.

Note that these changes did not make it into EF6 alpha 3, but they are in recent nightly builds.

What is now supported?

In a nutshell, the changes described below mean that:

  • Types not used in a Code First model but with the same simple name as types in the model will not cause EF to throw. For example, you can now have DTO types and entity types with the same names in the same assembly.
  • Nested types can be used.

Note that “simple name” means the name of the type excluding its namespace or any outer type names. The simple name of “My.Namespace.MyType” is “MyType” and the simple name of the nested type “My.Namespace.OuterType+InnerType” is “InnerType”.

What restrictions still exist?

Every type used in a given Code First model must still have a unique simple name. That is, using “My.Namespace1.Product” and “My.Namespace2.Product” in the same Code First model is not supported. Both these types can exist in the same assembly, and both can be used in different Code First models, or one can be used by Code First and the other not, but they can’t both be used by the same Code First model.

Also, these changes only apply to Code First. At the time of writing Database First and Model First still have the restrictions on types that they always had.

See Future Plans below for ideas on how we plan to remove these remaining restrictions in a future release of EF.

Background

Consider starting an EF application that contains a model in an EDMX file. EF reads the model from the EDMX file and then must find the CLR types that should be used with this model. For POCO entities this is done by scanning through assemblies that might contain the types and looking for matches. Matches are made by simple type name only—that is, there is no concept of matching namespaces or nested types. An exception is thrown if EF finds two types that have the same simple name and are therefore both potential matches.

This is clearly not a very good way of doing things even though arguments were made that it had to be this way. I won’t say any more about the decision to do it this way; right or wrong it is what it is.

Code First arrives

With Code First the CLR types that should be used do not need to be discovered—they are the “code” in Code First from which the model is created. So, theoretically, the above process should not have been needed for Code First. The problem was that until EF6 Code First was in a separate assembly to core EF with no access to internals. It therefore worked by creating an EDMX in memory and pushing that to core EF, which then loaded the EDMX and was forced to discover types again using the process described above.

What changed?

With the move out of the .NET Framework for EF6, Code First and the core code are now all in EntityFramework.dll. This has allowed what we refer to as “metadata unification”. That is, Code First now doesn’t create an EDMX in memory, but rather creates runtime metadata directly. (At the time of writing the MSL part of the EDMX is still created as XML because its validation at runtime is tightly coupled to reading this data from XML.)

This metadata unification was a very significant and non-trivial task, but now that it has been done it opens the door for other changes. (One of these is stored proc mapping in Code First—one of the reasons this is coming late in the EF6 cycle is because it makes use of this metadata unification.)

With metadata unification Code First now annotates the model it builds with CLR type information. This type information can then be used directly by the runtime so that for Code First the process described above is no longer needed. This means that:

  • Nested types work with Code First because the discovery mechanism that doesn’t understand them is no longer used
  • Types not used in the Code First model don’t have any impact because core EF no longer needs to try to find the correct types to use

Future plans

As stated above, every type used in a given model must still have a unique simple name. This is because every type in the conceptual model (the CSDL part of an EDMX) is still included in the same conceptual model namespace. The conceptual model (and in particular the CSDL XML schema) is not setup to deal well with types in the same model but in different namespaces. However, this is something we want to tackle post EF6 such that EF can use any number of types with the same simple name so long as they have different namespaces or outer types.

We also plan to change the way type discovery happens for Database First and Model First when an EDMX file is loaded. It’s not clear exactly how this will be done, but the most promising approach seems to be to use DbSet/ObjectSet entity type information from the context coupled with the model shape in order to discover the CLR types to use. This should effectively remove the assembly scanning and simple name matching that Database First and Model First currently use. (And we can then hopefully dump this code entirely from EntityFramework.dll.)

It’s worth noting that using DbSet/ObjectSet information could break those using Database First or Model First without using DbSets or ObjectSets. It’s not clear that anybody is doing this, but if you are now would be a great time to contact the EF team!

Posted in Code First, Entity Framework | Tagged , , | 1 Comment

EF enums and spatial types on .NET 4

In EF5 some features (such as enums and spatial types) are only available when targeting .NET 4.5. This is because EF5 relies on core EF libraries in the .NET Framework. With EF6 this changes because the core EF code is now included in EntityFramework.dll and recent commits to the code make all EF features (except async) available on .NET 4. This includes enums, spatial support, TVFs, auto-compiled queries and other EF perf improvements, together with many smaller changes/bug fixes in the core code. Continue reading

Posted in Entity Framework, Open Source | Tagged , , | 2 Comments

EF6 Extensibility and Configuration

Introduction

I just published two posts to the Entity Framework CodePlex site that cover some changes we are making to EF6 to improve extensibility and code-based configuration. These posts provide conceptual overviews of the features with relevant design and implementation details. The idea is that people who are interested in where EF is going can read posts like this and provide feedback on the direction, design, and implementation. Providing this kind of feedback is an important way to contribute to EF without even having to write any code. Continue reading

Posted in Entity Framework, Extensibility, Open Source | Tagged , | 3 Comments

So you want to contribute to EF? Part 5: High-level architecture

This is the fifth part of a series providing some background to those who may want make contributes to the Entity Framework. In this post I’ll give an extremely high-level overview of the EF architecture. Continue reading

Posted in Open Source | Tagged , , | 3 Comments