-
It is my pleasure to announce that Synergex has released their Synergy/DE Data Provider for .NET with support for the Entity Framework. The Synergy/DE Data Provider for .NET enables developers to access Synergy DBMS databases from .NET applications and Visual Studio 2008 and to take advantage of the Entity Framework and LINQ.
For more information, see the Synergex announcement page about the release here. Congratulations to everyone at Synergex who contributed to the release!
Enjoy!
Elisa Flasko
Program Manager, Data Programmability
-
Overview
This post covers a new Entity Framework extension called Code Only. Code Only allows you to use the Entity Framework using POCO entities and without an EDMX file, i.e. with ‘Code Only’. This walkthrough shows you how to use the first release of Code Only, which is a very early and limited preview of our long term plans for Code Only. To get an idea of where Code Only is heading look at this post on the EF Design Blog.
Code Only ships as part of the Microsoft Entity Framework Feature CTP 1. The CTP works on top of the latest version of the Entity Framework released as part of .NET 4.0 Beta1, and you can download it here.
Requirements
- This walkthrough requires Visual Studio 2010 Beta 1
- The Microsoft Entity Framework Feature CTP1, that can be downloaded from here.
- A local SQL Server 2008 Express instance has to be installed as SQLEXPRESS. Otherwise, changes to the connection string in the web.config file or regenerating the database from the included SQL scripts may be necessary.
- Download and extract the initial solution attached to this post.
Read More…
-
Overview
This post covers a new Entity Framework extension called POCO Templates. POCO Templates is a T4 template and associated include files, that allow you to generate POCO classes or Plain Old CLR Objects for use with the Entity Framework. T4 templates are used because T4 makes it easy to customize your Entities.
POCO Templates ship as part of the Microsoft Entity Framework Feature CTP 1. The CTP works on top of the latest version of the Entity Framework released as part of .NET 4.0 Beta1, and you can download it here.
Requirements
- This walkthrough requires Visual Studio 2010 Beta 1
- The Microsoft Entity Framework Feature CTP1, that can be downloaded from here.
- A local SQL Server 2008 Express instance has to be installed as SQLEXPRESS. Otherwise, changes to the connection string in the web.config file or regenerating the database from the included SQL scripts may be necessary.
- Download and extract the initial solution attached to this post.
Read More…
-
Overview
The goal of the following walkthrough is to demonstrate a basic scenario for the use of Self Tracking Entities with Entity Framework. Self Tracking Entities is a feature included in the Microsoft Entity Framework Community Technology Preview 1, which consists of a new API added to the ObjectContext and ObjectSet classes (implemented as extension methods for the Feature CTP) and a code-generation template based on Text Template Transformation Toolkit (T4) technology included in Visual Studio.
Self Tracking Entities are domain classes that do not have any dependency on Entity Framework but include mechanisms that allow them to track changes on scalar and complex property values, references and collections within themselves, independently of the Entity Framework.
The first scenario we are trying to address with Self Tracking Entities is one in which a WCF service exposes a series of operations that return entity graphs, then a client application can manipulate that graph and submit the modifications to a service operation that validates and performs the updates to a database store using Entity Framework.
Requirements
- This walkthrough requires Visual Studio 2010 Beta 1
- The Microsoft Entity Framework Feature CTP1, that can be downloaded from here.
- A local SQL Server 2008 Express instance has to be installed as SQLEXPRESS. Otherwise, changes to the connection string in the web.config file or regenerating the database from the included SQL scripts may be necessary.
- Download and extract the initial solution attached to this post.
Read More...
-
Today we are announcing the availability of the Microsoft Entity Framework Feature CTP 1 for the .NET Framework 4.0 Beta 1. You can download the Feature CTP 1 from here. This Feature CTP enables a number of scenarios that we've mentioned on the blog previously and now have a set of walk throughs for everybody to start playing with the features:
1) Better N-Tier Support with Self Tracking Entities
2) POCO (Plain Old CLR Objects) entity code generation via the POCO Template
3) Writing only code and having it work with the Entity Framework via Code Only.
We weren’t able to ship these capabilities in the .NET Framework 4.0 Beta 1 so we’ve decided to release them alongside the Beta. This CTP is an early preview of these features and as such we’re looking for lots of feedback on these components. This functionality is currently not scheduled to be part of the .NET Framework 4.0 and we expect to release another CTP of these features based on the feedback we get from you. Make sure to enter bugs via Microsoft Connect for the Visual Studio 2010 & .NET Framework 4.0 Beta located here. You can also discuss them in the forum for the Entity Framework 4.0 Beta.
Carl Perry
Program Manager, Entity Framework
-
If you have been watching this blog, you know that I have been discussing the various aspects of POCO capabilities we added to Entity Framework 4.0. POCO support makes it possible to do persistence ignorance with Entity Framework in a way that was never possible with Entity Framework 3.5.
If you missed the series on POCO, I’ve listed them here for your convenience. It might be a good idea to quickly check these out.
POCO in Entity Framework : Part 1 – The Experience
POCO in Entity Framework : Part 2 – Complex Types, Deferred Loading and Explicit Loading
POCO in Entity Framework : Part 3 – Change Tracking with POCO
In this post, I’d like to look at how we might be able to take our example a bit further and use some of the common patterns such as Repository and Unit Of Work so that we can implement persistence specific concerns in our example.
Expanding on our Northwind based example a bit further, let’s say I am interested in supporting the following Customer entity oriented operations:
- Query for a customer by ID
- Searching for Customer by Name
- Adding a new Customer to the database
I also want to be able to query for a product based on ID.
Finally, given a customer, I would like to be able to add an Order to the database
Before we get into the details, there are two things I’d like to get out of the way first:
- There is more than one “correct” way to approach this problem. I’ll likely be making many simplifying assumptions as I go – the objective is to show a very high level sketch of how you might implement the two patterns to solve the problem at hand.
- Normally, when using TDD, I’d start out with tests and use my tests to evolve my design incrementally. Since I’m not following TDD in this example, please bear with me if you see me doing things like defining an interface upfront, instead of letting tests and commonalities dictate the need for an interface, etc.
Implementing the Repository
Let’s start with the work we have to do on Customer entity and look at what a repository for dealing with Customer might look like:
public interface ICustomerRepository
{
Customer GetCustomerById(string id);
IEnumerable<Customer> FindByName(string name);
void AddCustomer(Customer customer);
}
This repository interface seems to meet all the requirements around Customer:
- GetCustomerById should allow me to get a single customer entity by primary key
- FindByName should allow me to search for customers
- AddCustomer should allow me to add customer to the database
This sounds good to me for the moment. Defining an interface like this for your repository is a good idea, especially if you are interested in writing tests using mocks or fakes and it allows for better unit testing by keeping your database out of the equation entirely. There are blog posts coming in the future that cover testability, mocks and fakes, etc.
You might take this interface definition a bit further and define a common IRepository for dealing with concerns that are common for multiple repository types. This is fine thing to do if you see that it works for you. I don’t necessarily see the need yet for this particular example and so I’ll pass on it for now. It is entirely possible that this becomes important as you add more repositories and refactor.
Let’s take this repository and see how we might build an implementation of it that leverages Entity Framework to enable data access.
First of all, I need an ObjectContext that I can use to query for data. You might be tempted to handle ObjectContext instantiation as a part of the repository’s constructor – but it is a good idea to leave that concern out of the repository and deal with that elsewhere.
Here’s my constructor:
public CustomerRepository(NorthwindContext context)
{
if (context == null)
throw new ArgumentNullException("context");
_context = context;
}
In the above snippet, NorthwindContext is my typed ObjectContext type.
Let’s now provide implementations for the methods required by our ICustomerRepository interface.
GetCustomerById is trivial to implement, thanks to LINQ. Using standard LINQ operators, we can implement GetCustomerById like this:
public Customer GetCustomerById(string id)
{
return _context.Customers.Where(c => c.CustomerID == id).Single();
}
Similarly, FindByName could look like this. Once again, LINQ support makes this trivial to implement:
public IEnumerable<Customer> FindByName(string name)
{
return _context.Customers.Where( c => c.ContactName.StartsWith(name)
).ToList();
}
Note that I chose to expose the results as IEnumerable<T> – you might choose to expose this as an IQueryable<T> instead. There are implications to doing this – in this case, I am not interested in exposing additional IQueryable based query composition over what I return from my repository.
And finally, let’s see how we might implement AddCustomer:
public void AddCustomer(Customer customer)
{
_context.Customers.AddObject(customer);
}
You may be tempted to also implement the save functionality as a part of the AddCustomer method. While that may work for this simple example, it is generally a bad idea – this is exactly where the Unit of Work comes in and we’ll see in a bit how we can use the this pattern to allow us to implement and coordinate Save behavior.
Here’s the complete implementation of CustomerRepository that uses Entity Framework for handling persistence:
public class CustomerRepository : ICustomerRepository
{
private NorthwindContext _context;
public CustomerRepository(NorthwindContext context)
{
if (context == null)
throw new ArgumentNullException("context");
_context = context;
}
public Customer GetCustomerById(string id)
{
return _context.Customers.Where(c => c.CustomerID == id).Single();
}
public IEnumerable<Customer> FindByName(string name)
{
return _context.Customers.Where(c => c.ContactName.StartsWith(name))
.AsEnumerable<Customer>();
}
public void AddCustomer(Customercustomer)
{
_context.Customers.AddObject(customer);
}
}
Here’s how we might use the repository from client code:
CustomerRepository repository = new CustomerRepository(context);
Customer c = new Customer( ... );
repository.AddCustomer(c);
context.SaveChanges();
For dealing with my Product and Order related requirements, I could define the following interfaces (and build implementations much like CustomerRepository). I’ll leave the details out of this post for brevity.
public interface IProductRepository
{
Product GetProductById(int id);
}
public interface IOrderRepository
{
void AddOrder(Order order);
}
Implementing Unit of Work Pattern using ObjectContext
You may have noticed this already; even though we didn’t implement any specific pattern to explicitly allow us to group related operations into a unit of work, we are already getting Unit of Work functionality for free with NorthwindContext (our typed ObjectContext).
The idea is that I can use the Unit of Work to group a set of related operations – the Unit of Work keeps track of the changes that I am interested in until I am ready to save them to the database. Eventually, when I am ready to save, I can do that.
I can define an interface like this to define a “Unit of Work”:
public interface IUnitOfWork
{
void Save();
}
Note that with a Unit of Work, you might also choose to implement Undo / Rollback functionality. When using Entity Framework, the recommended approach to undo is to discard your context with the changes you are interested in undoing.
I already mentioned that our typed ObjectContext (NorthwindContext) supports the Unit of Work pattern for the most part. In order to make things a bit more explicit based on the contract I just defined, I can change my NorthwindContext class to implement the IUnitOfWork interface:
public class NorthwindContext : ObjectContext, IUnitOfWork
{
public void Save()
{
SaveChanges();
}
. . .
I have to make a small adjustment to our repository implementation after this change:
public class CustomerRepository : ICustomerRepository
{
private NorthwindContext _context;
public CustomerRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
_context = unitOfWork as NorthwindContext;
}
public Customer GetCustomerById(string id)
{
return _context.Customers.Where(c => c.CustomerID == id).Single();
}
public IEnumerable<Customer> FindByName(string name)
{
return _context.Customers.Where(c => c.ContactName.StartsWith(name))
.AsEnumerable<Customer>();
}
public void AddCustomer(Customer customer)
{
_context.Customers.AddObject(customer);
}
}
That’s it – we now have our IUnitOfWork friendly repository, and you can use the IUnitOfWork based context to even coordinate work across multiple repositories. Here’s an example of adding an order to the database that requires the work of multiple repositories for querying data, and ultimately saving rows back to the database:
IUnitOfWork unitOfWork = new NorthwindContext();
CustomerRepository customerRepository = new CustomerRepository(unitOfWork);
Customer customer = customerRepository.GetCustomerById("ALFKI");
ProductRepository productRepository = new ProductRepository(unitOfWork);
Product product = productRepository.GetById(1);
OrderRepository orderRepository = new OrderRepository(unitOfWork);
Order order = new Order(customer);
order.AddNewOrderDetail(product, 1);
orderRepository.AddOrder(order);
unitOfWork.Save();
What’s quite interesting to see is how little code we had to write in order to enable data access using Repository and Unit of Work patterns on top of Entity Framework. Entity Framework’s LINQ support and out of the box Unit of Work functionality makes it trivial to build repositories on top of Entity Framework.
Another thing to note is that a lot of what I’ve covered in this post has nothing to do with Entity Framework 4.0 specifically – all of these general principles will work with Entity Framework 3.5 as well. But being able to use Repository and Unit of Work like I have shown here on top of our POCO support is really telling of what’s possible in Entity Framework 4.0. I hope you find this useful.
Lastly, I’ll reiterate that there are many ways of approaching this topic, and there are many variations of solutions that will fit your needs when working with Entity Framework, Repository and Unit of Work. You might choose to implement a common IRepository interface. You might also choose to implement a Repository<TEntity> base class that gives you some common repository functionality across all your repositories.
Try some of the various approaches and see what works for you. What I’ve covered here is only a general guideline – but I hope it is enough to get you going. More importantly, I hope this shows you how it is possible to use the POCO support we have introduced in Entity Framework 4.0 to help you build a domain model that is Entity Framework friendly without needing you to compromise on the basic principles around persistence ignorance.
The project that includes some of the code I showed is attached to this post. Stay tuned as we’ll likely have more to say on this topic when we discuss unit testing, TDD and testability in one of our future posts.
Faisal Mohamood
Program Manager, Entity Framework
-
As a part of formulating our long term strategy for ADO.NET, we have had several discussions with number of our customers, internal and external partners, and MVPs to better align our development efforts to ensure we are delivering the right technologies according to our customers’ highest priority needs. One of the key intent of these discussions and the associated research was to understand the needs and requirements of customers who develop applications with Oracle using “System.Data.OracleClient” (OracleClient). OracleClient is the ADO.NET provider for Oracle developed by Microsoft and ships as a part of the .NET Framework.
We learned that a significantly large portion of customers use our partners’ ADO.NET providers for Oracle; with regularly updated support for Oracle releases and new features. In addition, many of the third party providers are able to consistently provide the same level of quality and support that customers have come to expect from Microsoft. This is strong testament of our partners support for our technologies and the strength of our partner ecosystem. It is our assessment that even if we made significant investments in ADO.Net OracleClient to bring it at parity with our partners based providers, customers would not have a compelling reason to switch to ADO.Net OracleClient.
The Decision
After carefully considering all the options and talking to our customers, partners, and MVPs it was decided to deprecate OracleClient as a part of our ADO.NET roadmap.
Recommendation and Guidance:
System.Data.OracleClient will be available in the upcoming 4.0 release of .NET Framework; however, it will be marked as deprecated. This will have no impact to existing applications and these applications will continue to work as expected. Developing new applications which use OracleClient will be supported; however, warnings will be raised if the applications are compiled against .Net 4.0. Once compiled, no warnings or errors will be generated while running these applications. We strongly recommend customers to use our partners’ ADO.NET Provider for Oracle instead of continuing to use Microsoft’s OracleClient for new application development.
Microsoft will continue to provide hotfixes for critical issues in System.Data.OracleClient as per the standard support policy for .Net Framework 4.0. We will also continue to make critical bug fixes in future service packs for .Net Framework 4.0.
Thank you,
Himanshu Vasishth
Program Manager, ADO.NET OracleClient
-
In my last post on POCO, I mentioned the fact that there are two types of change tracking possibilities with POCO: Snapshot based Change Tracking and Notification based Change Tracking with Proxies. In this post, I would like to drill into both options a bit further and cover the advantages and disadvantages of both, along with the implications of using either approach. We will also be posting ideas on the EF Design Blog regarding some of the feedback we have received so far about POCO support in Entity Framework 4.0.
Snapshot based Change Tracking (pure POCO without proxies)
As I mentioned in Part 2 of this series, Snapshot based change tracking is what you get with pure POCO entities that don’t use proxies to handle change tracking. This is a simple change tracking solution that relies on complete snapshots of before and after values being maintained by the Entity Framework. These values are compared during SaveChanges to determine what has truly changed from their original values. In this model, unless you are using Lazy loading, the runtime type of your entities is the same as you define for your POCO entities.
There really isn’t anything problematic with this approach, and if you care about the runtime purity of your entity types without the use of proxies, it is perfectly fine to rely on this approach and take the route of pure POCO entities that don’t rely on proxy types for additional functionality.
The only catch with Snapshot based change tracking is that there are a few things you have to be aware of: because there is no direct notification of changes to the Entity Framework anytime your objects change, Entity Framework’s Object State manager will go out of sync with your own object graph.
Let’s take an example to see how this manifests itself:
Customer customer = (from c in context.Customers
where c.CustomerID == "ALFKI"
select c).Single();
ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(customer);
Console.WriteLine("Customer object state: {0}", ose.State); // Unchanged
customer.Country = "UK";
Console.WriteLine("Customer object state: {0}", ose.State); // Still Unchanged
In this example, Customer is a pure POCO type. Unlike with EntityObject or IPOCO based entities, making changes to the entity doesn’t automatically keep the state manager in sync because there is no automatic notification between your pure POCO entities and the Entity Framework. Therefore, upon querying the state manager, it thinks that the customer object state is Unchanged even though we have explicitly made a change to one of the properties on the entity.
If you were to perform SaveChanges without choosing to acceptChangesDuringSave, you will see that the state becomes Modified after the save. This is because the snapshot based change tracking kicked in during save and detected the change. Of course, the default SaveChanges call will leave the state back to Unchanged since the default Save behavior is to accept changes during save.
We’ll discuss more about what to do when you would actually need to keep things in sync between your objects, the object graph and the state manager in a little bit. But first let’s look at the other type of change tracking that’s available to you with POCO.
Notification based Change Tracking with Proxies
This is a different solution if you care about very efficient and up to date change tracking as you make changes to your entity values, relationships and object graph: Proxy based Change Tracking. You can leverage proxy based change tracking for a particular entity type if you declare all mapped properties on that entity type as virtual.
Entities that are tracked using change tracking proxies will always be in sync with the Entity Framework’s Object state manager because the proxies will notify the Entity Framework of the changes to values and relationships as each change happens. On the whole, this makes it more efficient to track changes because the object state manager can skip comparing original and current values of properties that it knows haven’t changed.
For all intents and purposes, the change tracking behavior you get with proxies is identical to the change tracking behavior you get with EntityObject based non-POCO entities or IPOCO entities.
Let’s take the same example:
Customer customer = (from c in context.Customers
where c.CustomerID == "ALFKI"
select c).Single();
ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(customer);
Console.WriteLine("Customer object state: {0}", ose.State); // Unchanged
customer.Country = "UK";
Console.WriteLine("Customer object state: {0}", ose.State); // Modified
The example is self explanatory – Object State Manager was notified of the changes as you made changes to your entity. There is no additional overhead you have to incur during SaveChanges.
Proxy based change tracking does however mean that the runtime type of your entities is not exactly the same type you defined – rather, it is a subclass of your own type. This can be undesirable in many cases (such as serialization) and you have to choose the approach that best works within the constraints and the requirements of your application and domain.
Keeping the State Manager in Sync without using Proxies
There are pros and cons to both approaches and it certainly won’t be surprising that the simplicity and elegance of non proxy based pure POCO will mean that it becomes the default choice for many of you. So let’s look at how you can keep the state manager in sync with your object graph when you work in this mode.
ObjectContext.DetectChanges()
There is one method that matters the most when you work with snapshot based pure POCO entities: ObjectContext.DetectChanges().
This API should be used explicitly whenever you have made changes to your object graph, and it will inform the state manager that it needs to sync up with your graph.
ObjectContext.SaveChanges will implicitly invoke DetectChanges by default, so you don’t need to explicitly call DetectChanges if all you are doing is making a series of changes to your objects and immediately performing a Save. However, keep in mind that depending on the size of your graph, DetectChanges may turn out to be expensive (also DetectChanges might be unnecessary depending on what you are doing) and therefore it is possible for you to skip DetectChanges that happens implicitly during SaveChanges - more on this when we discuss SaveChanges additions that are new to Entity Framework 4.0.
Let’s take a look at how DetectChanges impacts our example we looked at earlier:
Customer customer = (from c in context.Customers
where c.CustomerID == "ALFKI"
select c).Single();
ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(customer);
Console.WriteLine("Customer object state: {0}", ose.State); // Unchanged
customer.Country = "UK";
Console.WriteLine("Customer object state: {0}", ose.State); // Still Unchanged
context.DetectChanges();
Console.WriteLine("Customer object state: {0}", ose.State); // Modified
Calling DetectChanges explicitly brings the state manager in sync with the state of your objects.
Because DetectChanges is potentially expensive, it isn’t called explicitly during the other APIs on ObjectContext that rely on the state manager being in sync with the object graph. As a result, you have to call DetectChanges whenever you are performing state dependent operations on the context.
The behavior of the following APIs in Object Servces depend on the current state in the ObjectStateManager and therefore could be affected if knowledge aobut the part of the graph on which they operate is out of sync with the actual state of the graph:
ObjectContext API:
- AddObject
- Attach
- AttachTo
- DeleteObject
- Detach
- GetObjectByKey
- TryGetObjectByKey
- ApplyCurrentValues
- ApplyPropertyChanges
- ApplyOriginalValues
- Refresh
- ExecuteQuery
ObjectStateManager API:
- ChangeObjectState
- ChangeRelationshipState
- GetObjectStateEntry
- TryGetObjectStateEntry
- GetObjectStateEntries
ObjectStateEntry API:
EntityCollection/EntityReference API:
New Overloads for SaveChanges
In Entity Framework 3.5, there were two possibilities when invoking ObjectContext.SaveChanges():
- SaveChanges() – The parameterless option allowed you to save changes, and also accept changes implicitly
- SaveChanges(bool acceptChangesDuringSave) – This option allowed you to opt out of the default behavior of “accept changes during save”. You will have to explicitly use AcceptAllChanges to accept changes after the save.
With DetectChanges behavior added to the mix, it was obvious that adding additional overloads would clutter the API. In order to address this problem, the SaveOptions flags enum was introduced:
[Flags]
public enum SaveOptions
{
None = 0,
DetectChangesBeforeSave = 1,
AcceptChangesAfterSave = 2,
}
SaveChanges now includes an overload that looks like this:
public virtual int SaveChanges(SaveOptions options);
SaveOptions will allow us (the Entity Framework team) to extend the API in a much more manageable way should we need to add additional options in the future.
But this overload is also interesting for another reason: Note that this overload of SaveChanges is virtual. In Entity Framework 4.0, you can override the SaveChanges behavior with your own behavior customization, as a part of the ObjectContext derived implementations that you might choose to write. Whether or not you are using POCO support in EF, this will allow you add customizations in a way that was not possible with Entity Framework 3.5.
That pretty much wraps up most of the things I wanted to highlight about POCO in Entity Framework 4.0. Stay tuned for a write-up on using Patterns with Entity Framework next.
Faisal Mohamood
Program Manager, Entity Framework Team
-
Firebird recently announced the RTM of FirebirdClient 2.5. This new release now provides full support for the Entity Framework. To learn more about FirebirdClient 2.5 check out Jiri’s blog at http://blog.vyvojar.cz/jirka/archive/2009/05/22/ann-firebirdclient-2-5-final-released.aspx or access the download page at http://www.firebirdsql.org/index.php?op=files&id=netprovider
Elisa Flasko
Program Manager, Data Programmability
-
This week the team was able to make available in VB, 7 of our Entity Framework Samples that were previously only available in C#. We would like to say a huge THANK YOU to one of our wonderful VB MVPs, Jim Wooley, who graciously offered his help to get translate these samples and make them available to community. The newly added samples include
· EF Extensions
· Entity Framework Lazy Loading
· Persistence Ignorance (POCO) Adapter for Entity Framework V1
· Entity Framework Documentation Samples (3 new samples)
· Entity Framework Query Samples
Check out our newly added VB Samples for the Entity Framework at http://code.msdn.microsoft.com/adonetefx
Elisa Flasko
Program Manager, Data Programmability
-
In my post last week on the POCO Experience in Entity Framework, I covered the fundamentals of POCO support in Entity Framework 4.0. In this post, I’ll cover a few more aspects related to POCO.
Complex Types
Complex Types are supported in POCO just like they are with regular EntityObject based entities. All you have to do is declare your complex types as POCO classes and then use them for declaring the complex type based properties on your POCO entities.
As an example, here’s an InventoryDetail complex type to represent a part of my Product entity:
public class InventoryDetail
{
public Int16 UnitsInStock { get; set; }
public Int16 UnitsOnOrder { get; set; }
public Int16 ReorderLevel { get; set; }
}
My Product class now has been modified to include a property of this type to group the inventory detail fields:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int SupplierID { get; set; }
public string QuantityPerUnit { get; set; }
public decimal UnitPrice { get; set; }
public InventoryDetail InventoryDetail { get; set; }
public bool Discontinued { get; set; }
public Category Category { get; set; }
}
You can then do everything you are used to doing with Complex Types. Here’s how I use it in a query:
var outOfStockProducts = from c in context.Products
where c.InventoryDetail.UnitsInStock == 0
select c;
As you can see, Complex Type support with POCO is really straightforward to use. There are a couple of things you need to keep in mind when using complex types support with POCO:
- You must define your Complex Type as a class. Structs are not supported.
- You cannot use inheritance with your complex type classes.
While we are on the topic of Complex Types, I thought I’d mention one other thing: Did you know that the Entity Framework designer in Visual Studio 2010 supports complex type declarations?
In Visual Studio 2008, you had to manually add the Complex Type declaration to the CSDL. That is all history with the Complex Type support in the designer in Visual Studio 2010.
And what’s cool is that because Visual Studio 2010 supports Multi-Targeting, you can use this capability when building applications that target .NET Framework 3.5, using Entity Framework 3.5 as well!
Deferred/Lazy Loading
In my sneak preview post on Deferred Loading two weeks ago, I mentioned that there is now Deferred Loading support in Entity Framework. It comes as no surprise then that the default code-generated entity types out of the box based on EntityObject will offer Deferred Loading. If you are wondering whether Deferred Loading is supported with POCO objects, then I think you will be happy to know that you can get Deferred Loading with POCO as well.
There are two things you need to do in order to get Deferred Loading support with POCO entities:
- Declare the property that you would like to load lazily as virtual. These properties can be any collection type that implements ICollection<T> or they can be a reference representing a 1/0..1 relationship.
For instance, here’s a part of the updated Category entity class which I have modified to support Deferred Loading:
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public byte[] Picture { get; set; }
public virtual List<Product> Products { get; set; }
...
2. Enable deferred loading on the context:
context.ContextOptions.DeferredLoadingEnabled = true;
That’s it. You will now get automatic Deferred Loading for your POCO types without having to do anything else.
So how exactly does this work and what’s going on under the covers?
The reason why this works is because when I marked my collection property as virtual, this allowed the Entity Framework to provide a proxy instance for my POCO type at runtime, and it is this proxy that does automatic deferred loading. The proxy instance is based on a type that derives from my own POCO entity class - so all functionality you have provided is preserved. From a developer point of view, this allows you to write persistence ignorant code even when deferred loading might be a requirement.
If you were to inspect the actual instance in the debugger, you will see that the underlying type for the instance is different from the original type that I declared:
While the Entity Framework does its best to provide automatic deferred loading with minimal friction, this is something you need to be aware of when dealing with manual creation of instances that you want to then add or attach, or when you serialize/deserialize instances.
Manual instantiation of Proxy instances for POCO entities
In order to enable creation of proxy instances for adding/attaching, you can use the CreateObject factory method on ObjectContext for creating entity instances:
Category category = context.CreateObject<Category>();
Try to keep this in mind and use CreateObject when creating instances that you want to then use with the Entity Framework.
More Efficient Change Tracking with “Change Tracking Proxies”
The standard POCO entities we have talked about until now rely on snapshot based change tracking – i.e. the Entity Framework will maintain snapshots of before values and relationships of the entities so that they can be compared with current values later during Save. However, this comparison is relatively expensive when compared to the way change tracking works with EntityObject based entities.
There is another type of proxy that will allow you to get better performance out of change tracking with POCO entities.
If you are familiar with IPOCO, you know that IEntityWithChangeTracker was one of the interfaces you were required to implement to provide change notifications to the Entity Framework.
Change Tracking proxies subclass your POCO entity class to provide you with this capability during runtime without requiring you to implement the IPOCO interfaces yourself.
In many ways, you get the best of both worlds with this approach: You get persistence ignorance with POCO classes and you get the performance of EntityObject / IPOCO when it comes to change tracking.
To get change tracking proxies, the basic rule is that your class must be public, non-abstract or non-sealed. Your class must also implement public virtual getters/setters for all properties that are persisted. Finally, you must declare collection based relationship navigation properties as ICollection<T> only. They cannot be a concrete implementation or another interface that derives from ICollection<T> (a difference from the Deferred Loading proxy)
Here’s an example of my POCO class for Product that will give me more efficient proxy based change tracking at runtime:
public class Product
{
public virtual int ProductID { get; set; }
public virtual string ProductName { get; set; }
public virtual int SupplierID { get; set; }
public virtual string QuantityPerUnit { get; set; }
public virtual decimal UnitPrice { get; set; }
public virtual InventoryDetail InventoryDetail { get; set; }
public virtual bool Discontinued { get; set; }
public virtual Category Category { get; set; }
}
Once again, keep in mind that you must use CreateObject for creating proxy instances you want to then add or attach to the context. But pure POCO entities that don’t rely on proxies and proxy based entities can work together. You need to only use CreateObject when dealing with proxy based entities.
What if I want both Deferred Loading and better change tracking for the same POCO type?
The two are not mutually exclusive and you don’t have to choose between a Deferred Loading proxy and a Change Tracking proxy. If you want Deferred Loading and efficient change tracking, you just have to follow the rules for Change Tracking via proxies, and enable Deferred Loading. Change Tracking proxies will give you deferred loading if deferred loading is enabled.
Explicit Loading
All this deferred loading capability is great – but there are plenty of you out there that want to be in full control of how you load related entities. You might even choose to go the route of pure POCO without having to resort to any of the automatic proxy generation done for you.
This is a perfectly acceptable (and preferable in many cases) and you can use explicit loading of relationships and be in complete control of how you query for data from the database.
There are two options for doing Explicit Load with POCO:
One is to use ObjectContext.LoadProperty and specify the name of the navigation property you want to load:
context.LoadProperty(beveragesCategory, "Products");
This gets the job done – but it isn’t very type safe as you can see. If I don’t have the right name of the navigation property here, I will get a runtime exception.
Some of you might actually prefer this:
context.LoadProperty(beveragesCategory, c => c.Products);
I can use a lambda expression to specify the property that I want to load explicitly, and this is offers more type safety.
So that’s about everything I planned on covering in the second post. There’s more to come however – in the final part of this series, we’ll go over some of the things to be aware of when dealing with pure POCO (non proxy) instances and keeping things in sync between your object graph and the Object State Manager. We will also cover variations of SaveChanges that you might want to be aware of.
In the meantime, check out the sample code that I have updated to cover some of the things we have talked about in this post.
Faisal Mohamood
Program Manager, Entity Framework
-
I’ve been asked a few times lately whether DataSet is or will be supported in Silverlight, so I thought I’d post the answer here.
There are no plans to add DataSet into future releases of Silverlight. However we are investigating work to bridge existing DataSet investments to new data technologies. Below are three different approaches that can be used to build data-centric applications in Silverlight now.
ADO.NET Data Services is the primary approach to creating data-centric applications in Silverlight. There is a client api within Silverlight for accessing these RESTful Services. ADO.NET Data Services exposes data through ATOM and JSON which are standard technologies when building rich internet applications. Here is a link to get started on this technology: http://msdn.microsoft.com/en-us/data/bb931106.aspx.
In addition to ADO.NET Data Services, there is .Net RIA Services. The project aims to allow developers to build rich internet applications on Silverlight using Visual Studio. This isn't a released project yet, but there May 2009 preview that developers can use. Here is a link to this preview: http://silverlight.net/forums/53.aspx.
Lastly, if there are requirements to expose data through Web Services rather than RESTful Services, we would recommend using WCF. These services can be accessed within Silverlight and would expose specific data contracts, not DataSets. Here is a link to get started on this approach: http://msdn.microsoft.com/en-us/magazine/cc794260.aspx. We welcome any feedback from the community on this.
Thanks,
Chris Robinson
Program Manager - DataSet
-
Last week I mentioned in the sneak preview on POCO that support for POCO entities is one of the new capabilities we have added to Entity Framework 4.0. This week, I’d like to go into the details of POCO support in Entity Framework 4.0.
There’s quite a bit to discuss here, including:
- Overall POCO experience in Entity Framework 4.0
- Change Tracking in POCO
- Relationship Fix-up
- Complex Types
- Deferred (Lazy) Loading and Explicit Loading
- Best Practices
In this post, I will focus primarily on the overall experience so that you can get started with POCO in Entity Framework 4.0 right away. I’d like to use a simple example that we can walk through so you can see what it feels like to use POCO in Entity Framework 4.0. I will use the Northwind database, and we’ll continue to build on this example in subsequent posts.
Step 1 – Create the Model, turn off default Code Generation
While POCO allows you to write your own entity classes in a persistence ignorant fashion, there is still the need for you to “plug in” persistence and EF metadata so that your POCO entities can be materialized from the database and persisted back to the database. In order to do this, you will still need to either create an Entity Data Model using the Entity Framework Designer or provide the CSDL, SSDL and MSL metadata files exactly as you have done with Entity Framework 3.5. So first I’ll generate an EDMX using the ADO.NET Entity Data Model Wizard.
- Create a class library project for defining your POCO types. I named mine NorthwindModel. This project will be persistence ignorant and will not have a dependency on the Entity Framework.
- Create a class library project that will contain your persistence aware code. I named mine NorthwindData. This project will have a dependency on Entity Framework (System.Data.Entity) in addition to a dependency on the NorthwindModel project.
- Add New Item to the NorthwindData project and add an ADO.NET Entity Data Model called Northwind.edmx (doing this will automatically add the dependency to the Entity Framework).
- Go through “Generate from Database” and build a model for the Northwind database.
- For now, select Categories and Products as the only two tables you are interested in adding to your Entity Data model.
Now that I have my Entity Data model to work with, there is one final step before I start to write code : turn off code generation. After all you are interested in POCO – so remove the Custom Tool that is responsible for generating EntityObject based code for Northwind.edmx. This will turn off code generation for your model.
We are now ready to write our POCO entities.
Step 2 – Code up your POCO entities
I am going to write simple POCO entities for Category and Product. These will be added to the NorthwindModel project. Note that what I show here shouldn’t be taken as best practice and the intention here is to demonstrate the simplest case that works out of the box. We will extend and customize this to our needs as we go forward and build on top of this using Repository and Unit of Work patterns later on.
Here’s sample code for our Category entity:
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public byte[] Picture { get; set; }
public List<Product> Products { get; set; }
}
Note that I have defined properties for scalar properties as well as navigation properties in my model. The Navigation Property in our model translates to a List<Product>.
Similarly, Product entity can be coded like this:
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int SupplierID { get; set; }
public string QuantityPerUnit { get; set; }
public decimal UnitPrice { get; set; }
public Int16 UnitsInStock { get; set; }
public Int16 UnitsOnOrder { get; set; }
public Int16 ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public Category Category { get; set; }
}
In this case, since the relationship allows only one Category that a Product can belong to, we have a reference to a Category (unlike the List<T> collection we have for modeling the Navigation Property in Category).
Step 3 – Code up your Entity Framework Context
The last thing I have to do in order to pull all of this together is to provide a context implementation (much like the ObjectContext implementation you get when you use default code generation). The context is the glue that brings persistence awareness into your application, and it will allow you to compose queries, materialize entities as well as save changes back to the database. The context will be a part of the NorthwindData project.
For simplicity, I will include our context into the same class library that has our entity types – but when we discuss patterns such as Repository and Unit of Work, we will set it up such that you have a pure POCO class library without any persistence concerns.
Here’s a simple context implementation for our scenario:
public class NorthwindContext : ObjectContext
{
public NorthwindContext() : base("name=NorthwindEntities",
"NorthwindEntities")
{
_categories = CreateObjectSet<Category>();
_products = CreateObjectSet<Product>();
}
public ObjectSet<Category> Categories
{
get
{
return _categories;
}
}
private ObjectSet<Category> _categories;
public ObjectSet<Product> Products
{
get
{
return _products;
}
}
private ObjectSet<Product> _products;
}
Note that ObjectSet<T> is a more specialized ObjectQuery<T> that we introduced in Entity Framework 4.0.
That’s it – now you have pure POCO entities with a simple context that will allow you to write queries like this:
NorthwindContext db = new NorthwindContext();
var beverages = from p in db.Products
where p.Category.CategoryName == "Beverages"
select p;
The entities that are materialized are pure POCO entities, and you can make and persist changes much like you would with regular EntityObject or IPOCO entities. You get all the services provided by Entity Framework - the only difference is that you are using pure POCO entities.
There are many possibilities here as far as how we can improve on this simplified example. Before we get into that however, I would like to get some basic questions out of the way.
Do I need an Entity Data Model before I can use POCO?
Yes – POCO support in Entity Framework 4.0 simply removes the need of having persistence specific concerns in your entity classes. There is still the need for you to have a CSDL/SSDL/MSL (collectively EDMX) metadata so that the Entity Framework is able to use your entities along with the metadata in order to enable data access. There is a separate effort that we are working on that will allow you to do true “code-first” development without the need to have a predefined EDMX model. A community preview of this feature will be released to the web in the coming months. We will roll this into the product the first chance we get. As always, your feedback will be helpful.
Do I have to always hand-craft these entities and the context?
No – there is a very powerful and flexible code generation mechanism in Entity Framework 4.0 that is based on T4 as Alex blogged about here. You can provide your own templates that allow you to build your entities in a way that you see fit. We are also working on providing standard out of the box templates that will generate POCO entities for you.
How is metadata mapped when using POCO entities?
In Entity Framework 3.5, both EntityObject and IPOCO based entities relied on the use of mapping attributes that were meant for decorating and mapping the entity types and properties back to the corresponding elements in the Conceptual model. Entity Framework 4.0 introduces convention based mapping for allowing mapping of Entity Types, Properties, Complex Types and Relationships back to the conceptual model without the need for explicit decoration. The simple rule here is that Entity Type names, Property names and Complex Types names used in your POCO classes must match those defined by the conceptual model. Namespace names are ignored and don’t have to match between the class definition and the conceptual model.
Do I need to have public getters and setters for all properties in my entity classes?
You can use any access modifier on your POCO type’s properties as long as none of the mapped properties are virtual and as long as you don’t require partial trust support. When running in partial trust, there are specific requirements on the visibility of access modifiers on your entity classes. We will be documenting the complete set of access modifiers that are supported when partial trust is involved.
What types of collections are supported for collection based navigation properties?
Any collection that is an ICollection<T> will be supported. If you don’t initialize the field with a concrete type that is an ICollection<T> type, then an List<T> type will be provided upon materialization.
Can I have uni-directional relationships? For instance – I would like to have a Category property in my Product class, but I don’t want to have a Products collection in my Category class.
Yes – this is supported. The only restriction here is that your entity types have to reflect what is defined by the model. If you are not interested in having the navigation property for one side of the relationship, then remove it from the model completely.
Is Deferred (Lazy) Loading supported with POCO?
Yes – Deferred (Lazy) loading is supported with POCO through the use of proxy types that are used to provide automatic lazy loading behavior on top of your POCO classes. This is something that we’ll cover when we get to deferred loading – until then know that eager loading via the use of “Include” is also supported, like so:
var beverageCategory = (from c in context.Categories
.Include("Products")
where c.CategoryName == "Beverages"
select c).Single();
If I were to use Deferred (Lazy) Loading, I don’t have to do this – we’ll discuss that when we discuss proxies.
Fixing up Relationships
There are two types of fix-ups to be aware of: 1)Fix-up during query, and 2) Fix-up during changes to your entities/relationships
Fix-up during Query
Fix-up during query happens when you load related entities using separate queries on the same ObjectContext. For instance, if I were to query for a category instance Beverages, and later query for a product instance Chai (that is in Category Beverages), I would want chai.Category to point to the instance of the Beverages category without additional work.
This is automatic and works today.
Fix-up during changes to your entities/relationships
This is the relationship fix-up between two entities when I add/remove an entity that is related to another entity or alter relationships. Think of this as the case when I create a new product called “Diet Chai” and want to associate it with the Beverages category.
In Beta1 of Entity Framework 4.0, you do not get automatic relationship fix-up in this case with POCO entities. When dealing with relationships that change between entities, you will have to make sure that your POCO types include the logic to manage fix-up on both ends of the relationship correctly.
For instance, in my Northwind example, I have defined the following method on Category to support adding / removing of Orders.
public void AddProduct(Product p)
{
if (Products == null)
{
Products = new List<Product>();
}
if (!Products.Contains(p))
{
Products.Add(p);
}
p.Category = this;
}
In general, it is good to use a pattern like this to support adding/removing related items rather than using the relationship collection to add/remove related entities. You also have options of making the getter/setter for the actual EF backed collection private/internal to support more fine grained access – but as mentioned earlier, some of this depends on the requirements as to whether you require partial trust support or not.
So we have covered quite a bit of ground in this “quick look” at the overall POCO experience. There’s quite a lot more to talk about – and I will be continuing this discussion early next week. In the meantime, take a look at the complete solution (attached) if you are interested in the sample code covering all the concepts we covered here. Please keep in mind that you must have a local instance of Northwind database installed on the machine where you are running this sample.
In my next post we will look at Complex Types, Change Tracking, Proxies, Lazy Loading and Eager Loading. Until then, please look through the MSDN Documentation on POCO here for more details on POCO support in Entity Framework 4.0.
Let us know what you think!
Faisal Mohamood
Program Manager, Entity Framework
-
With the release of Visual Studio 2010 Beta 1, we have released supporting Entity Framework documentation. Below are links to documentation for new Entity Framework features and scenarios. Along with feedback on the Entity Framework, we would like to hear your feedback on the documentation. What works for you? What doesn’t? What’s missing? We’ll work to incorporate your feedback in future releases.
Thanks!
Entity Framework User Education Team
Persistence-Ignorant Objects
You can use your own custom data classes together with your data model without making any modifications to the data classes themselves. This means that you can use "plain old" CLR objects (POCO), such as existing domain objects, with your Entity Framework application. For more information, see Persistence Ignorant Objects (Entity Framework).
Deferred Loading of Related Objects
With deferred loading, also known as lazy loading, related objects are automatically loaded from the data source when you access a navigation property. For more information, see Shaping Query Results (Entity Framework).
Functions in LINQ to Entities Queries
The EntityFunctions and SqlFunctions classes provide access to canonical and database functions from LINQ to Entities queries. The EdmFunctionAttribute allows a CLR method to serve as a proxy for a function defined in the conceptual model or storage model. For more information, see Calling Functions in LINQ to Entities Queries.
Customized Object Layer Code Generation
You can configure the ADO.NET Entity Data Model Designer to use text templates to generate customized object layer code. For more information, see How to: Customize Object Layer Code Generation.
Model-First Support
The Create Database Wizard enables you to do conceptual modeling first, and then create a database that supports the model. For more information, see How to: Generate a Database from a Conceptual Model.
Complex Type Support in the Entity Data Model Designer
The ADO.NET Entity Data Model Designer now supports complex types. For more information, see the following topics:
Naming Service
The Entity Data Model Wizard and the Update Model Wizard provide the option of using singular or plural forms of Entity, EntitySet, and NavigationProperty names to make application code more readable. For more information, see Choose Your Database Objects Dialog Box (Entity Data Model Wizard) and Choose Your Database Objects Dialog Box (Update Model Wizard).
Improved Model Browser Functionality
The Model Browser window of the ADO.NET Entity Data Model Designer enables you to delete objects from the storage model and to search the conceptual and storage models for a specified string. For more information, see Model Browser Window and How to: Delete Objects from the Storage Model.
User-Defined Functions (Entity SQL)
Entity SQL supports calling user-defined functions in a query. For more information, see User-Defined Functions (Entity SQL).
-
Beta 1 has shipped! You can find information about the Beta and pointers to the download here. So far on this bog we’ve talked, at a high level, about the scenarios and capabilities that our team has been focused on in this release. In the coming weeks and months, we’ll be drilling in depth on these topics. Starting tomorrow we’ll have the first post on POCO, so stay tuned. Beyond reading and posting questions to the team blog, you can look to the forums for help and information, read the what’s new in ADO.NET section in the MSDN documentation, and file bugs on the connect site. We look forward to hearing any feedback you have on the updates we’ve made.
Carl Perry
Program Manager, Entity Framework